@mcp-apps/api-tools-mcp-server
Version:
MCP server for interacting with APIs and web services
118 lines • 5.63 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ApiService = void 0;
const axios_1 = __importDefault(require("axios"));
const token_manager_1 = require("./token-manager");
class ApiService {
static async callApi(config) {
try {
const url = this.buildUrl(config.endpoint, config.path, config.queryParams);
const headers = {
'Content-Type': 'application/json',
...config.headers || {},
};
// Add authentication headers if specified
if (config.authType === 'bearer' && config.authConfig?.token) {
headers['Authorization'] = `Bearer ${config.authConfig.token}`;
}
else if (config.authType === 'basic' && config.authConfig?.username) {
const username = config.authConfig.username;
const password = config.authConfig.password || '';
const base64Auth = Buffer.from(`${username}:${password}`).toString('base64');
headers['Authorization'] = `Basic ${base64Auth}`;
}
else if (config.authType === 'interactive') {
try {
const token = await (0, token_manager_1.getAccessToken)(config.authConfig?.clientId, config.authConfig?.tenantId, config.authConfig?.scopes, config.authConfig?.useBroker ?? true);
headers['Authorization'] = `Bearer ${token}`;
}
catch (authError) {
console.error('Interactive authentication error:', authError);
return {
success: false,
status: 401,
error: `Authentication error: ${authError.message || 'Unknown authentication error'}`
};
}
}
const response = await (0, axios_1.default)({
method: config.method,
url,
headers,
data: config.body,
// Ensure response type is set to handle both JSON and non-JSON responses
responseType: 'json',
// Don't automatically transform non-JSON responses to prevent parsing errors
transformResponse: [(data) => {
if (typeof data === 'string') {
try {
return JSON.parse(data);
}
catch (e) {
// If we can't parse as JSON, return the raw data
console.warn(`Response from ${url} is not valid JSON`);
return data;
}
}
return data;
}]
});
return {
success: true,
status: response.status,
data: response.data,
headers: response.headers,
};
}
catch (error) {
// Log useful debugging information console.error('Error making API call:', error);
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.error('Response status:', error.response.status);
// Only log response data if it's not huge
if (typeof error.response.data === 'string' && error.response.data.length < 1000) {
console.error('Response data:', error.response.data);
}
else if (typeof error.response.data === 'object') {
console.error('Response data:', JSON.stringify(error.response.data).substring(0, 1000) + '...');
}
}
else if (error.request) {
// The request was made but no response was received
console.error('Request was made but no response was received');
}
else {
// Something happened in setting up the request that triggered an Error
console.error('Error setting up request:', error.message);
}
return {
success: false,
status: error.response?.status || 500,
error: error.response?.data?.detail || error.message || 'Unknown error occurred',
response: error.response, // Include the full response for debugging
};
}
}
static buildUrl(endpoint, path, queryParams) {
// Remove trailing slashes from endpoint
const baseUrl = endpoint.endsWith('/') ? endpoint.slice(0, -1) : endpoint;
// Ensure path starts with a forward slash if provided
const formattedPath = path ? (path.startsWith('/') ? path : `/${path}`) : '';
// Build query string from params if any
let queryString = '';
if (queryParams && Object.keys(queryParams).length > 0) {
const params = new URLSearchParams();
for (const [key, value] of Object.entries(queryParams)) {
params.append(key, value);
}
queryString = `?${params.toString()}`;
}
return `${baseUrl}${formattedPath}${queryString}`;
}
}
exports.ApiService = ApiService;
//# sourceMappingURL=api-service.js.map