breathe-api
Version:
Model Context Protocol server for Breathe HR APIs with Swagger/OpenAPI support - also works with custom APIs
133 lines • 5.12 kB
JavaScript
import { readFileSync, existsSync } from 'fs';
import { join } from 'path';
import { createEnvironmentSecret } from '../utils/security-utils.js';
export function loadCustomConfig() {
const configPaths = [
process.env.MCP_CONFIG_PATH,
join(process.cwd(), 'mcp-config.json'),
join(process.cwd(), '.mcp', 'config.json'),
join(process.env.HOME || '', '.mcp', 'config.json')
].filter(Boolean);
for (const configPath of configPaths) {
if (configPath && existsSync(configPath)) {
try {
const configContent = readFileSync(configPath, 'utf-8');
return JSON.parse(configContent);
}
catch (error) {
console.error(`Failed to parse config from ${configPath}:`, error);
}
}
}
if (process.env.MCP_CONFIG) {
try {
return JSON.parse(process.env.MCP_CONFIG);
}
catch (error) {
console.error('Failed to parse MCP_CONFIG environment variable:', error);
}
}
if (process.env.API_BASE_URL) {
return createConfigFromEnv();
}
return null;
}
function createConfigFromEnv() {
const config = {
name: process.env.API_NAME || 'Custom API',
environments: {},
defaultEnvironment: 'production'
};
if (process.env.API_BASE_URL) {
config.environments.production = {
displayName: 'Production',
baseUrl: process.env.API_BASE_URL,
swaggerUrl: process.env.API_SWAGGER_URL,
auth: getAuthFromEnv('')
};
}
const environments = ['production', 'staging', 'development', 'sandbox'];
for (const env of environments) {
const prefix = env.toUpperCase();
const baseUrl = process.env[`API_${prefix}_BASE_URL`];
if (baseUrl) {
config.environments[env] = {
displayName: env.charAt(0).toUpperCase() + env.slice(1),
baseUrl,
swaggerUrl: process.env[`API_${prefix}_SWAGGER_URL`],
auth: getAuthFromEnv(prefix)
};
}
}
return config;
}
function getAuthFromEnv(prefix) {
const envPrefix = prefix ? `API_${prefix}_` : 'API_';
const authType = process.env[`${envPrefix}AUTH_TYPE`];
if (authType === 'none') {
return { type: 'none' };
}
const token = process.env[`${envPrefix}TOKEN`] || process.env[`${envPrefix}BEARER_TOKEN`];
if (token) {
return { type: 'bearer', token };
}
const apiKey = process.env[`${envPrefix}API_KEY`];
if (apiKey) {
return {
type: 'api-key',
apiKey,
apiKeyHeader: process.env[`${envPrefix}API_KEY_HEADER`] || 'X-API-Key'
};
}
const username = process.env[`${envPrefix}USERNAME`];
const password = process.env[`${envPrefix}PASSWORD`];
if (username && password) {
return { type: 'basic', username, password };
}
return { type: 'none' };
}
export function customConfigToEnvironments(config) {
const environments = {};
for (const [envName, envConfig] of Object.entries(config.environments)) {
if (!envConfig)
continue;
const env = envName;
environments[env] = {
name: env,
displayName: envConfig.displayName || `${config.name} - ${env}`,
description: envConfig.description || `${config.name} ${env} environment`,
baseUrl: envConfig.baseUrl,
isActive: env === (config.defaultEnvironment || 'production'),
auth: {
type: envConfig.auth?.type || 'none',
username: envConfig.auth?.username,
password: envConfig.auth?.password ? createEnvironmentSecret(envConfig.auth.password) : undefined,
token: envConfig.auth?.token ? createEnvironmentSecret(envConfig.auth.token) : undefined,
apiKey: envConfig.auth?.apiKey ? createEnvironmentSecret(envConfig.auth.apiKey) : undefined,
apiKeyHeader: envConfig.auth?.apiKeyHeader
},
endpoints: envConfig.endpoints ? Object.fromEntries(Object.entries(envConfig.endpoints).map(([key, endpoint]) => [
key,
{
path: endpoint.path,
method: endpoint.method?.toUpperCase() || 'GET',
description: endpoint.description,
rateLimit: undefined
}
])) : undefined,
metadata: {
region: undefined,
version: undefined,
lastUpdated: undefined,
contact: undefined,
...(envConfig.swaggerUrl && { swaggerUrl: envConfig.swaggerUrl }),
...(envConfig.headers && { customHeaders: envConfig.headers })
}
};
}
if (Object.keys(environments).length === 0) {
throw new Error('No environments configured. Please provide at least one environment.');
}
return environments;
}
//# sourceMappingURL=custom-config.js.map