UNPKG

leanix-pathfinder-mcp-server

Version:

MCP Server for LeanIX Pathfinder API - Enterprise Architecture Management Platform

176 lines 6.22 kB
export class LeanIXClient { config; token = null; constructor(config) { this.config = config; } async ensureValidToken() { if (this.token && this.isTokenValid()) { return; } try { const credentials = `${this.config.clientId}:${this.config.clientSecret}`; const encodedCredentials = btoa(credentials); const response = await fetch(`${this.config.baseUrl}/services/mtm/v1/oauth2/token`, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': `Basic ${encodedCredentials}` }, body: 'grant_type=client_credentials' }); if (!response.ok) { throw new Error(`OAuth authentication failed: ${response.status} ${response.statusText}`); } const tokenData = await response.json(); this.token = { ...tokenData, expires_at: Date.now() + (tokenData.expires_in * 1000) - 60000 // 1 minute buffer }; } catch (error) { throw new Error(`OAuth authentication failed: ${error.message}`); } } isTokenValid() { if (!this.token || !this.token.expires_at) { return false; } return Date.now() < this.token.expires_at; } async makeRequest(method, url, config) { await this.ensureValidToken(); const fullUrl = url.startsWith('http') ? url : `${this.config.baseUrl}${url}`; const headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', ...config?.headers }; if (this.token) { headers.Authorization = `Bearer ${this.token.access_token}`; } const fetchConfig = { method, headers, }; if (config?.body && (method === 'POST' || method === 'PUT' || method === 'PATCH' || method === 'DELETE')) { fetchConfig.body = typeof config.body === 'string' ? config.body : JSON.stringify(config.body); } const response = await fetch(fullUrl, fetchConfig); let data; const contentType = response.headers.get('content-type'); if (contentType?.includes('application/json')) { data = await response.json(); } else { data = await response.text(); } if (!response.ok) { throw new Error(`HTTP ${response.status}: ${data?.errorMessage || data || response.statusText}`); } const responseHeaders = {}; response.headers.forEach((value, key) => { responseHeaders[key] = value; }); return { data, status: response.status, headers: responseHeaders }; } async get(url, config) { return this.makeRequest('GET', url, config); } async post(url, data, config) { return this.makeRequest('POST', url, { ...config, body: data }); } async put(url, data, config) { return this.makeRequest('PUT', url, { ...config, body: data }); } async patch(url, data, config) { return this.makeRequest('PATCH', url, { ...config, body: data }); } async delete(url, config) { return this.makeRequest('DELETE', url, config); } // Utility method for handling multipart form data async postMultipart(url, formData, config) { await this.ensureValidToken(); const fullUrl = url.startsWith('http') ? url : `${this.config.baseUrl}${url}`; const headers = { 'Accept': 'application/json', ...config?.headers }; if (this.token) { headers.Authorization = `Bearer ${this.token.access_token}`; } const response = await fetch(fullUrl, { method: 'POST', headers, body: formData }); let data; const contentType = response.headers.get('content-type'); if (contentType?.includes('application/json')) { data = await response.json(); } else { data = await response.text(); } if (!response.ok) { throw new Error(`HTTP ${response.status}: ${data?.errorMessage || data || response.statusText}`); } const responseHeaders = {}; response.headers.forEach((value, key) => { responseHeaders[key] = value; }); return { data, status: response.status, headers: responseHeaders }; } // Utility method for downloading files async downloadFile(url, config) { await this.ensureValidToken(); const fullUrl = url.startsWith('http') ? url : `${this.config.baseUrl}${url}`; const headers = { ...config?.headers }; if (this.token) { headers.Authorization = `Bearer ${this.token.access_token}`; } const response = await fetch(fullUrl, { method: 'GET', headers }); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } return response; } // Method to set workspace context setWorkspaceId(workspaceId) { this.config.workspaceId = workspaceId; } getWorkspaceId() { return this.config.workspaceId; } // Helper method to build query parameters buildQueryParams(params) { const searchParams = new URLSearchParams(); for (const [key, value] of Object.entries(params)) { if (value !== undefined && value !== null) { if (Array.isArray(value)) { value.forEach(v => searchParams.append(key, String(v))); } else { searchParams.append(key, String(value)); } } } const queryString = searchParams.toString(); return queryString ? `?${queryString}` : ''; } } //# sourceMappingURL=client.js.map