UNPKG

askexperts

Version:

AskExperts SDK: build and use AI experts - ask them questions and pay with bitcoin on an open protocol

118 lines 4.48 kB
import { AskExpertsHttp } from "../../mcp/index.js"; import { debugMCP, debugError, enableAllDebug, enableErrorDebug, } from "../../common/debug.js"; /** * Start the HTTP server with the given options * * @param options Command line options */ export async function startHttpServer(options) { // Get server type (default to "mcp") const type = options.type || "mcp"; // Try to get OpenAI API key from options or environment variables let openaiApiKey = options.openaiApiKey || process.env.OPENAI_API_KEY; // Try to get OpenAI base URL from options or environment variables let openaiBaseUrl = options.openaiBaseUrl || process.env.OPENAI_BASE_URL; // If type is "smart", validate OpenAI API key and base URL if (type === "smart") { if (!openaiBaseUrl) { // Override with a fake url that will trigger the use // of AE protocol to talk to our expert-based LLM openaiBaseUrl = "https://askexperts.io"; } else { // Validate OpenAI API key if (!openaiApiKey) { throw new Error("OpenAI API key is required for smart MCP. Use --openai-api-key option or set OPENAI_API_KEY environment variable."); } // Validate OpenAI base URL if (!openaiBaseUrl) { throw new Error("OpenAI base URL is required for smart MCP. Use --openai-base-url option or set OPENAI_BASE_URL environment variable."); } } } // Try to get discovery relays from options or environment variables let discoveryRelays = options.relays; if (!discoveryRelays && process.env.DISCOVERY_RELAYS) { discoveryRelays = process.env.DISCOVERY_RELAYS.split(",").map((relay) => relay.trim()); } try { // Create the HTTP server const server = new AskExpertsHttp({ port: options.port, basePath: options.basePath, type, discoveryRelays, openaiApiKey, openaiBaseUrl, }); // Handle SIGINT/SIGTERM (Ctrl+C) const sigHandler = async () => { debugMCP("\nReceived SIGINT. Shutting down..."); try { // Stop the proxy server await server.stop(); debugMCP("Proxy server shutdown complete."); } catch (error) { debugError("Error during shutdown:", error); } finally { // Exit the process process.exit(0); } }; process.on("SIGINT", sigHandler); process.on("SIGTERM", sigHandler); // Start the server server.start(); debugMCP("Press Ctrl+C to exit."); } catch (error) { debugError("Failed to start HTTP server:", error); throw error; } } /** * Helper function to parse comma-separated lists * @param value The comma-separated string * @returns Array of trimmed strings */ function commaSeparatedList(value) { return value.split(",").map((item) => item.trim()); } /** * Register the HTTP command with the CLI * * @param program The commander program */ export function registerHttpCommand(program) { program .command("http") .description("Launch an HTTP MCP server") .requiredOption("-p, --port <number>", "Port to listen on (default: 3000)", parseInt) .option("-r, --relays <items>", "Comma-separated list of discovery relays", commaSeparatedList) .option("-b, --base-path <string>", "Base path for the server") .option("-t, --type <string>", "Server type: 'mcp' or 'smart' (default: 'mcp')", (value) => { if (value !== "mcp" && value !== "smart") { throw new Error("Type must be either 'mcp' or 'smart'"); } return value; }) .option("-k, --openai-api-key <string>", "OpenAI API key (required if -u is set)") .option("-o, --openai-base-url <string>", "OpenAI base URL (custom URL for 'smart' type)") .option("-d, --debug", "Enable debug logging") .action(async (options) => { if (options.debug) enableAllDebug(); else enableErrorDebug(); try { await startHttpServer(options); } catch (error) { debugError("Error starting HTTP server:", error); process.exit(1); } }); } //# sourceMappingURL=http.js.map