Skip to main content
Glama
http-client.ts4.39 kB
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; import { GeneratedTool, ToolExecutionContext, RequestConfig } from '../types'; import { applyAuthentication } from './auth'; export class HttpClient { async executeRequest( context: ToolExecutionContext, args: Record<string, any> ): Promise<string> { try { const requestConfig = this.buildRequestConfig(context, args); const response = await axios(requestConfig); return this.formatResponse(response); } catch (error) { if (axios.isAxiosError(error)) { const status = error.response?.status || 'Unknown'; const message = error.response?.data || error.message; return `HTTP Error ${status}: ${JSON.stringify(message, null, 2)}`; } return `Request failed: ${error instanceof Error ? error.message : String(error)}`; } } private buildRequestConfig( context: ToolExecutionContext, args: Record<string, any> ): AxiosRequestConfig { const { tool, authConfig } = context; // Build URL with path parameters let url = this.buildUrl(tool, args); // Build headers let headers: Record<string, string> = { 'Content-Type': 'application/json', 'User-Agent': 'specbridge/1.0.0' }; // Apply authentication headers = applyAuthentication(headers, authConfig); // Add header parameters this.addHeaderParameters(tool, args, headers); // Build query parameters const params = this.buildQueryParameters(tool, args); // Build request body const data = this.buildRequestBody(tool, args); const config: AxiosRequestConfig = { method: tool.method.toLowerCase() as any, url, headers, timeout: 30000, // 30 second timeout }; if (Object.keys(params).length > 0) { config.params = params; } if (data !== null) { config.data = data; } return config; } private buildUrl(tool: GeneratedTool, args: Record<string, any>): string { let url = tool.baseUrl.replace(/\/$/, '') + tool.path; // Replace path parameters for (const param of tool.parameters) { if (param.in === 'path' && args[param.name] !== undefined) { url = url.replace(`{${param.name}}`, encodeURIComponent(String(args[param.name]))); } } return url; } private addHeaderParameters( tool: GeneratedTool, args: Record<string, any>, headers: Record<string, string> ): void { for (const param of tool.parameters) { if (param.in === 'header' && args[param.name] !== undefined) { headers[param.name] = String(args[param.name]); } } } private buildQueryParameters( tool: GeneratedTool, args: Record<string, any> ): Record<string, any> { const params: Record<string, any> = {}; for (const param of tool.parameters) { if (param.in === 'query' && args[param.name] !== undefined) { params[param.name] = args[param.name]; } } return params; } private buildRequestBody( tool: GeneratedTool, args: Record<string, any> ): any { if (!tool.requestBody) return null; // Look for 'body' or 'requestBody' in args if (args.body !== undefined) { return args.body; } if (args.requestBody !== undefined) { return args.requestBody; } // If no explicit body parameter, collect all non-parameter args const bodyArgs: Record<string, any> = {}; const paramNames = new Set(tool.parameters.map(p => p.name)); for (const [key, value] of Object.entries(args)) { if (!paramNames.has(key)) { bodyArgs[key] = value; } } return Object.keys(bodyArgs).length > 0 ? bodyArgs : null; } private formatResponse(response: AxiosResponse): string { const headers = Object.entries(response.headers) .map(([key, value]) => `${key}: ${value}`) .join('\n'); let body: string; if (typeof response.data === 'string') { body = response.data; } else if (response.data === null || response.data === undefined) { body = '(empty response)'; } else { body = JSON.stringify(response.data, null, 2); } return `Status: ${response.status} ${response.statusText}\n\nHeaders:\n${headers}\n\nBody:\n${body}`; } }

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/TBosak/specbridge'

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