UNPKG

@nekobato/chatgpt-websearch-mcp

Version:

A local MCP stdio server that provides access to the OpenAI (ChatGPT) API with web search capabilities for Claude Code and other MCP clients.

120 lines (119 loc) 4.02 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ChatGPTClient = void 0; const openai_1 = __importDefault(require("openai")); const models_js_1 = require("../utils/models.js"); class ChatGPTClient { openai; constructor(apiKey) { this.openai = new openai_1.default({ apiKey: apiKey || process.env.OPENAI_API_KEY, }); } createOpenAIClient(request) { const options = { apiKey: this.openai.apiKey, }; if (request.maxRetries !== undefined) { options.maxRetries = request.maxRetries; } if (request.timeoutMs !== undefined) { options.timeout = request.timeoutMs; } return new openai_1.default(options); } validateRequest(request) { if (!this.openai.apiKey) { throw new Error('OPENAI_API_KEY environment variable is not set'); } if (!(0, models_js_1.isSupportedModel)(request.model)) { throw new Error(`Unsupported model "${request.model}". Supported models are: ${models_js_1.ALL_SUPPORTED_MODELS.join(', ')}`); } } async chat(request) { this.validateRequest(request); const client = this.createOpenAIClient(request); try { return await this.callResponsesAPI(request, client, false); } catch (error) { throw new Error(`Failed to call ChatGPT: ${error.message}`); } } async *chatStream(request) { this.validateRequest(request); const client = this.createOpenAIClient(request); try { yield* this.streamResponsesAPI(request, client); } catch (error) { throw new Error(`Failed to call ChatGPT: ${error.message}`); } } async callResponsesAPI(request, client, stream) { const requestBody = { model: request.model, input: request.prompt, stream, tools: [ { type: 'web_search', search_context_size: request.searchContextSize || process.env.SEARCH_CONTEXT_SIZE || 'medium', }, ], tool_choice: 'auto', parallel_tool_calls: true, }; if (request.effort) { requestBody.reasoning = { effort: request.effort }; } if (request.verbosity) { requestBody.text = { verbosity: request.verbosity }; } if (request.maxTokens) { requestBody.max_output_tokens = request.maxTokens; } const completion = await client.responses.create(requestBody); const responseContent = completion.output_text || ''; return { content: responseContent, model: request.model, usage: completion.usage, }; } async *streamResponsesAPI(request, client) { const requestBody = { model: request.model, input: request.prompt, stream: true, }; if (request.effort) { requestBody.reasoning = { effort: request.effort }; } if (request.verbosity) { requestBody.text = { verbosity: request.verbosity }; } if (request.maxTokens) { requestBody.max_output_tokens = request.maxTokens; } const completion = await client.responses.create(requestBody); for await (const event of completion) { if (event.type === 'response.output_text.delta') { yield { content: event.delta, done: false, }; } } yield { content: '', done: true, }; } } exports.ChatGPTClient = ChatGPTClient;