chat_completion
Send chat completion requests to AI models through a unified gateway interface. Configure parameters like model selection, message history, and response controls to generate AI-powered text outputs.
Instructions
Send a chat completion request to the configured AI API provider (ANTHROPIC). Supports parameters like model, messages, temperature, max_tokens, stream, etc. Returns the raw response from the API without format conversion.
Custom AI model for enterprise use
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| model | No | Model to use for completion (default: claude-3-sonnet-20240229) | |
| messages | Yes | Array of message objects with role and content | |
| temperature | No | Controls randomness in the response (default: 0.7) | |
| max_tokens | No | Maximum number of tokens to generate (default: 4096) | |
| stream | No | Whether to stream the response | |
| top_p | No | Controls diversity via nucleus sampling | |
| frequency_penalty | No | Penalizes new tokens based on their frequency | |
| presence_penalty | No | Penalizes new tokens based on whether they appear in the text | |
| stop | No | Up to 4 sequences where the API will stop generating further tokens | |
| response_format | No | Format of the response (OpenAI only). Supports json_object and json_schema types. |
Implementation Reference
- src/index.ts:282-337 (handler)The main execution logic for the 'chat_completion' tool. Processes input parameters, applies configuration defaults, validates inputs, prepares API-specific request data and headers, sends HTTP POST to the AI provider's endpoint, and formats the response as MCP content. Handles errors appropriately.private async handleChatCompletion(params: ChatCompletionParams): Promise<any> { try { // Apply defaults from configuration const completionParams = { ...params, model: params.model || this.config.defaultModel, temperature: params.temperature ?? this.config.defaultTemperature, max_tokens: params.max_tokens ?? this.config.defaultMaxTokens, }; // Validate required parameters if (!completionParams.messages || completionParams.messages.length === 0) { throw new McpError( ErrorCode.InvalidParams, 'messages parameter is required and cannot be empty' ); } // Prepare request based on API format const requestData = this.prepareRequestData(completionParams); const headers = this.prepareHeaders(); // Construct URL based on API format let url = this.config.apiEndpoint; if (this.config.apiFormat === 'openai' && !url.endsWith('/chat/completions')) { url = url.endsWith('/') ? url + 'chat/completions' : url + '/chat/completions'; } // Make the API request const response = await this.httpClient.post(url, requestData, { headers }); return { content: [ { type: 'text', text: JSON.stringify(response.data, null, 2), }, ], }; } catch (error) { if (axios.isAxiosError(error)) { const errorMessage = error.response?.data?.error?.message || error.message; const statusCode = error.response?.status || 500; throw new McpError( ErrorCode.InternalError, `API request failed (${statusCode}): ${errorMessage}` ); } throw new McpError( ErrorCode.InternalError, `Unexpected error: ${error instanceof Error ? error.message : 'Unknown error'}` ); } }
- src/index.ts:267-276 (registration)Registers the CallToolRequestHandler which checks if the tool name is 'chat_completion' and dispatches to the handleChatCompletion method if matched.this.server.setRequestHandler(CallToolRequestSchema, async (request) => { if (request.params.name !== 'chat_completion') { throw new McpError( ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}` ); } return await this.handleChatCompletion(request.params.arguments as unknown as ChatCompletionParams); });
- src/index.ts:154-262 (registration)Registers the 'chat_completion' tool in the ListTools response, including name, detailed description, and comprehensive inputSchema defining all supported parameters with types, descriptions, defaults hints, and validation rules.tools: [ { name: 'chat_completion', description: `Send a chat completion request to the configured AI API provider (${this.config.apiFormat.toUpperCase()}). ` + `Supports parameters like model, messages, temperature, max_tokens, stream, etc. ` + `Returns the raw response from the API without format conversion.${customDescriptionInfo}`, inputSchema: { type: 'object', properties: { model: { type: 'string', description: `Model to use for completion${this.config.defaultModel ? ` (default: ${this.config.defaultModel})` : ''}`, }, messages: { type: 'array', description: 'Array of message objects with role and content', items: { type: 'object', properties: { role: { type: 'string', enum: ['system', 'user', 'assistant'], }, content: { type: 'string', }, }, required: ['role', 'content'], }, }, temperature: { type: 'number', description: `Controls randomness in the response${this.config.defaultTemperature ? ` (default: ${this.config.defaultTemperature})` : ''}`, minimum: 0, maximum: 2, }, max_tokens: { type: 'number', description: `Maximum number of tokens to generate${this.config.defaultMaxTokens ? ` (default: ${this.config.defaultMaxTokens})` : ''}`, minimum: 1, }, stream: { type: 'boolean', description: 'Whether to stream the response', default: false, }, top_p: { type: 'number', description: 'Controls diversity via nucleus sampling', minimum: 0, maximum: 1, }, frequency_penalty: { type: 'number', description: 'Penalizes new tokens based on their frequency', minimum: -2, maximum: 2, }, presence_penalty: { type: 'number', description: 'Penalizes new tokens based on whether they appear in the text', minimum: -2, maximum: 2, }, stop: { oneOf: [ { type: 'string' }, { type: 'array', items: { type: 'string' }, }, ], description: 'Up to 4 sequences where the API will stop generating further tokens', }, response_format: { type: 'object', description: 'Format of the response (OpenAI only). Supports json_object and json_schema types.', properties: { type: { type: 'string', enum: ['text', 'json_object', 'json_schema'], description: 'The type of response format', }, json_schema: { type: 'object', description: 'JSON schema definition (required when type is json_schema)', properties: { name: { type: 'string', description: 'Name of the schema', }, schema: { type: 'object', description: 'JSON schema object', }, strict: { type: 'boolean', description: 'Whether to use strict validation', }, }, required: ['name', 'schema'], }, }, required: ['type'], }, }, required: ['messages'], }, },
- src/index.ts:17-38 (schema)TypeScript interface defining the structure of ChatCompletionParams used throughout the implementation for type safety.interface ChatCompletionParams { model?: string; messages: Array<{ role: 'system' | 'user' | 'assistant'; content: string; }>; temperature?: number; max_tokens?: number; stream?: boolean; top_p?: number; frequency_penalty?: number; presence_penalty?: number; stop?: string | string[]; response_format?: { type: 'text' | 'json_object' | 'json_schema'; json_schema?: { name: string; schema: Record<string, any>; strict?: boolean; }; }; }
- src/index.ts:342-416 (helper)Helper function that transforms ChatCompletionParams into API-specific request payload for either OpenAI or Anthropic formats, handling differences like system message placement and parameter mapping.private prepareRequestData(params: ChatCompletionParams): any { if (this.config.apiFormat === 'anthropic') { // Convert to Anthropic format const systemMessage = params.messages.find(m => m.role === 'system'); const nonSystemMessages = params.messages.filter(m => m.role !== 'system'); const anthropicData: any = { model: params.model, messages: nonSystemMessages, max_tokens: params.max_tokens || 1024, }; if (systemMessage) { anthropicData.system = systemMessage.content; } if (params.temperature !== undefined) { anthropicData.temperature = params.temperature; } if (params.top_p !== undefined) { anthropicData.top_p = params.top_p; } if (params.stream !== undefined) { anthropicData.stream = params.stream; } if (params.stop) { anthropicData.stop_sequences = Array.isArray(params.stop) ? params.stop : [params.stop]; } return anthropicData; } else { // OpenAI format (default) const openaiData: any = { model: params.model, messages: params.messages, }; if (params.temperature !== undefined) { openaiData.temperature = params.temperature; } if (params.max_tokens !== undefined) { openaiData.max_tokens = params.max_tokens; } if (params.stream !== undefined) { openaiData.stream = params.stream; } if (params.top_p !== undefined) { openaiData.top_p = params.top_p; } if (params.frequency_penalty !== undefined) { openaiData.frequency_penalty = params.frequency_penalty; } if (params.presence_penalty !== undefined) { openaiData.presence_penalty = params.presence_penalty; } if (params.stop !== undefined) { openaiData.stop = params.stop; } if (params.response_format !== undefined) { openaiData.response_format = params.response_format; } return openaiData; } }