/**
* MCP Server Configuration
*
* Handles CLI flags, environment variables, and configuration file loading.
*/
// Package version - keep in sync with package.json
const VERSION = '0.1.4';
const HELP_TEXT = `
RelayPlane MCP Server v${VERSION}
Reduce AI context usage by 90%+ in multi-step workflows.
RelayPlane is BYOK - we don't charge for API usage.
Usage:
npx @relayplane/mcp-server [options]
Options:
--out-dir <path> Code generation output directory (default: ./servers/relayplane)
--max-daily-cost <n> Max daily spending in USD (default: 5.00)
--max-single-call-cost <n> Max per-call cost in USD (default: 0.50)
--max-calls-per-hour <n> Max requests per hour (default: 100)
--timeout <ms> Timeout in milliseconds (default: 30000)
--help, -h Show this help message
--version, -v Show version
Environment Variables:
OPENAI_API_KEY OpenAI API key
ANTHROPIC_API_KEY Anthropic API key
GOOGLE_API_KEY Google AI API key
XAI_API_KEY xAI API key
Examples:
# Add to Claude Code with API keys
claude mcp add relayplane -e OPENAI_API_KEY=sk-... -- npx @relayplane/mcp-server
# With budget limits
npx @relayplane/mcp-server --max-daily-cost 10 --max-single-call-cost 1
Documentation: https://relayplane.com/docs
`;
/**
* Check for --help or --version flags and exit if found.
* Returns true if the program should exit.
*/
export function handleHelpAndVersion(args: string[]): boolean {
if (args.includes('--help') || args.includes('-h')) {
console.log(HELP_TEXT);
return true;
}
if (args.includes('--version') || args.includes('-v')) {
console.log(VERSION);
return true;
}
return false;
}
export interface McpServerConfig {
// Code generation
codegenOutDir: string;
// Budget (tracks provider costs, not RelayPlane fees - we're BYOK)
maxDailyCostUsd: number;
maxSingleCallCostUsd: number;
maxCallsPerHour: number;
// Execution
defaultTimeoutMs: number;
maxConcurrentRuns: number;
// Providers
providers: {
openai?: { apiKey: string };
anthropic?: { apiKey: string };
google?: { apiKey: string };
xai?: { apiKey: string };
};
// Trace URL base
traceUrlBase: string;
}
const DEFAULT_CONFIG: McpServerConfig = {
codegenOutDir: './servers/relayplane',
maxDailyCostUsd: 5.00,
maxSingleCallCostUsd: 0.50,
maxCallsPerHour: 100,
defaultTimeoutMs: 30000,
maxConcurrentRuns: 3,
providers: {},
traceUrlBase: 'https://app.relayplane.com/runs',
};
let currentConfig: McpServerConfig = { ...DEFAULT_CONFIG };
/**
* Parse CLI arguments
*/
export function parseCliArgs(args: string[]): Partial<McpServerConfig> {
const config: Partial<McpServerConfig> = {};
for (let i = 0; i < args.length; i++) {
const arg = args[i];
if (arg === '--out-dir' && args[i + 1]) {
config.codegenOutDir = args[++i];
} else if (arg === '--max-daily-cost' && args[i + 1]) {
config.maxDailyCostUsd = parseFloat(args[++i]);
} else if (arg === '--max-single-call-cost' && args[i + 1]) {
config.maxSingleCallCostUsd = parseFloat(args[++i]);
} else if (arg === '--max-calls-per-hour' && args[i + 1]) {
config.maxCallsPerHour = parseInt(args[++i], 10);
} else if (arg === '--timeout' && args[i + 1]) {
config.defaultTimeoutMs = parseInt(args[++i], 10);
}
}
return config;
}
/**
* Load provider keys from environment variables
*/
export function loadProvidersFromEnv(): McpServerConfig['providers'] {
const providers: McpServerConfig['providers'] = {};
if (process.env.OPENAI_API_KEY) {
providers.openai = { apiKey: process.env.OPENAI_API_KEY };
}
if (process.env.ANTHROPIC_API_KEY) {
providers.anthropic = { apiKey: process.env.ANTHROPIC_API_KEY };
}
if (process.env.GOOGLE_API_KEY) {
providers.google = { apiKey: process.env.GOOGLE_API_KEY };
}
if (process.env.XAI_API_KEY) {
providers.xai = { apiKey: process.env.XAI_API_KEY };
}
return providers;
}
/**
* Initialize configuration from CLI args and environment
*/
export function initConfig(cliArgs: string[] = process.argv.slice(2)): McpServerConfig {
const cliConfig = parseCliArgs(cliArgs);
const providers = loadProvidersFromEnv();
currentConfig = {
...DEFAULT_CONFIG,
...cliConfig,
providers: { ...DEFAULT_CONFIG.providers, ...providers },
};
return currentConfig;
}
/**
* Get current configuration
*/
export function getConfig(): McpServerConfig {
return currentConfig;
}
/**
* Get provider API key
*/
export function getProviderKey(provider: string): string | undefined {
const providers = currentConfig.providers as Record<string, { apiKey: string } | undefined>;
return providers[provider]?.apiKey;
}
/**
* Check if provider is configured
*/
export function isProviderConfigured(provider: string): boolean {
return !!getProviderKey(provider);
}