Skip to main content
Glama
index.ts3.88 kB
#!/usr/bin/env node import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { z } from 'zod'; import dotenv from 'dotenv'; import { OpenAIService } from './services/openai.js'; import { SessionManager } from './services/session-manager.js'; import { askGPTSchema, handleAskGPT } from './tools/askGPT.js'; import { registerSessionTools } from './tools/session-tools.js'; dotenv.config(); const apiKey = process.env.OPENAI_API_KEY; if (!apiKey) { console.error('Error: OPENAI_API_KEY environment variable is required'); process.exit(1); } const server = new McpServer({ name: 'gpt-mcp', version: '2.0.0', }); const openaiService = new OpenAIService(apiKey); const sessionManager = new SessionManager(); function formatZodError(error: z.ZodError): string { const issue = error.issues[0]; const field = issue.path.join('.'); if (issue.code === 'invalid_enum_value') { const options = issue.options as string[]; const received = issue.received as string; // Add helpful descriptions for common fields const descriptions: Record<string, string> = { model: 'Available models', reasoning_effort: 'Reasoning levels (minimal=fastest, low, medium, high=most thorough)', verbosity: 'Response detail levels' }; const desc = descriptions[field] || 'Available options'; return `Invalid ${field} '${received}'. ${desc}: ${options.join(', ')}`; } if (issue.code === 'too_small') { return `${field} is required and cannot be empty`; } return `Invalid ${field}: ${issue.message}`; } server.registerTool( 'askGPT', { title: 'Ask GPT', description: 'Send a prompt to OpenAI GPT models with optional conversation context', inputSchema: { model: askGPTSchema.shape.model, prompt: askGPTSchema.shape.prompt, reasoning_effort: askGPTSchema.shape.reasoning_effort, verbosity: askGPTSchema.shape.verbosity, session_id: askGPTSchema.shape.session_id, }, }, async (params) => { try { const validatedParams = askGPTSchema.parse(params); const result = await handleAskGPT(validatedParams, openaiService, sessionManager); // Format output for better readability let formattedOutput = `Model: ${result.model}\n`; if (result.reasoning_effort) { formattedOutput += `Reasoning: ${result.reasoning_effort}\n`; } if (result.verbosity) { formattedOutput += `Verbosity: ${result.verbosity}\n`; } if (result.session_id) { formattedOutput += `Session: ${result.session_id}\n`; } if (result.tokens_used) { formattedOutput += `Tokens: ${result.tokens_used}\n`; } formattedOutput += `Time: ${result.timestamp}\n`; formattedOutput += `${'─'.repeat(40)}\n\n`; formattedOutput += result.response; return { content: [ { type: 'text', text: formattedOutput, }, ], }; } catch (error) { let errorMessage: string; if (error instanceof z.ZodError) { errorMessage = formatZodError(error); } else { errorMessage = `Error: ${error instanceof Error ? error.message : 'Unknown error'}`; } return { content: [ { type: 'text', text: errorMessage, }, ], isError: true, }; } } ); // Register session management tools registerSessionTools(server, sessionManager); async function main() { const transport = new StdioServerTransport(); await server.connect(transport); console.error('GPT-MCP server started successfully'); } main().catch((error) => { console.error('Failed to start server:', error); process.exit(1); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/bzzimmy/gpt-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server