Skip to main content
Glama
api-client.ts4.92 kB
import axios, { AxiosInstance, AxiosError } from 'axios'; import { BitbucketServerBuildSummary } from '../types/bitbucket.js'; export interface ApiError { status?: number; message: string; isAxiosError: boolean; originalError?: AxiosError; } export class BitbucketApiClient { private axiosInstance: AxiosInstance; private isServer: boolean; constructor( baseURL: string, username: string, password?: string, token?: string ) { this.isServer = !!token; const axiosConfig: any = { baseURL, headers: { 'Content-Type': 'application/json', }, }; // Use token auth for Bitbucket Server, basic auth for Cloud if (token) { // Bitbucket Server uses Bearer token axiosConfig.headers['Authorization'] = `Bearer ${token}`; } else { // Bitbucket Cloud uses basic auth with app password axiosConfig.auth = { username, password, }; } this.axiosInstance = axios.create(axiosConfig); } async makeRequest<T>( method: 'get' | 'post' | 'put' | 'delete', path: string, data?: any, config?: any ): Promise<T> { try { let response; if (method === 'get') { // For GET, config is the second parameter response = await this.axiosInstance[method](path, config || {}); } else if (method === 'delete') { // For DELETE, we might need to pass data in config if (data) { response = await this.axiosInstance[method](path, { ...config, data }); } else { response = await this.axiosInstance[method](path, config || {}); } } else { // For POST and PUT, data is second, config is third response = await this.axiosInstance[method](path, data, config); } return response.data; } catch (error) { if (axios.isAxiosError(error)) { const status = error.response?.status; const message = error.response?.data?.errors?.[0]?.message || error.response?.data?.error?.message || error.response?.data?.message || error.message; throw { status, message, isAxiosError: true, originalError: error } as ApiError; } throw error; } } handleApiError(error: any, context: string) { if (error.isAxiosError) { const { status, message } = error as ApiError; if (status === 404) { return { content: [ { type: 'text', text: `Not found: ${context}`, }, ], isError: true, }; } else if (status === 401) { return { content: [ { type: 'text', text: `Authentication failed. Please check your ${this.isServer ? 'BITBUCKET_TOKEN' : 'BITBUCKET_USERNAME and BITBUCKET_APP_PASSWORD'}`, }, ], isError: true, }; } else if (status === 403) { return { content: [ { type: 'text', text: `Permission denied: ${context}. Ensure your credentials have the necessary permissions.`, }, ], isError: true, }; } return { content: [ { type: 'text', text: `Bitbucket API error: ${message}`, }, ], isError: true, }; } throw error; } getIsServer(): boolean { return this.isServer; } async getBuildSummaries( workspace: string, repository: string, commitIds: string[] ): Promise<BitbucketServerBuildSummary> { if (!this.isServer) { // Build summaries only available for Bitbucket Server return {}; } if (commitIds.length === 0) { return {}; } try { // Build query string with multiple commitId parameters const apiPath = `/rest/ui/latest/projects/${workspace}/repos/${repository}/build-summaries`; // Create params with custom serializer for multiple commitId parameters const response = await this.makeRequest<BitbucketServerBuildSummary>( 'get', apiPath, undefined, { params: { commitId: commitIds }, paramsSerializer: (params: any) => { // Custom serializer to create multiple commitId= parameters if (params.commitId && Array.isArray(params.commitId)) { return params.commitId.map((id: string) => `commitId=${encodeURIComponent(id)}`).join('&'); } return ''; } } ); return response; } catch (error) { // If build-summaries endpoint fails, return empty object (graceful degradation) console.error('Failed to fetch build summaries:', error); return {}; } } }

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/pdogra1299/bitbucket-mcp-server'

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