UNPKG

huggingface-mcp-server

Version:

MCP Server for HuggingFace inference endpoints with custom LoRA and story generation

172 lines (171 loc) 7.28 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.startServer = void 0; exports.startHttpServer = startHttpServer; const express_1 = __importDefault(require("express")); const handler_1 = require("./handler"); /** * Starts an HTTP server for MCP * @param port The port to listen on * @param apiKey The HuggingFace API key * @returns A Promise that resolves when the server is started */ async function startHttpServer(port = 3000, apiKey) { const app = (0, express_1.default)(); app.use(express_1.default.json()); // Log server startup console.log(`Starting HuggingFace MCP Server in HTTP mode on port ${port}`); console.log(`API Key is ${apiKey ? 'provided' : 'missing'}`); // Add request logging middleware app.use((req, res, next) => { console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`); next(); }); const HUGGINGFACE_API_KEY = apiKey; // Routes app.get('/', (req, res) => { res.json({ message: 'HuggingFace MCP Server is running' }); }); app.post('/v1/tools', (req, res) => { const tools = [ { type: 'function', function: { name: 'generate_image', description: 'Generate an image based on a text prompt using Flux model, with optional custom LoRA', parameters: { type: 'object', properties: { prompt: { type: 'string', description: 'Description of the image to generate' }, num_inference_steps: { type: 'number', description: 'The number of denoising steps of the image. More steps usually lead to higher quality at the cost of slower inference', default: 25 }, height: { type: 'number', description: 'Height of the image in pixels', default: 1024 }, width: { type: 'number', description: 'Width of the image in pixels', default: 1024 }, guidance_scale: { type: 'number', description: 'Controls how much the image generation follows the text prompt. Higher values make the image stick more closely to the input text', default: 3.5 }, seed: { type: 'number', description: 'A starting point to initiate the generation process, use 0 for a random seed', default: 0 }, num_images_per_prompt: { type: 'number', description: 'Number of images to generate with the settings', default: 1 }, lora_name: { type: 'string', description: 'Name of the custom LoRA model on HuggingFace (e.g., "username/lora-model-name")' } }, required: ['prompt'] } } }, { type: 'function', function: { name: 'generate_story', description: 'Generate a story based on a prompt', parameters: { type: 'object', properties: { prompt: { type: 'string', description: 'Prompt for story generation' } }, required: ['prompt'] } } } ]; // Log that tools were requested console.log('Tools requested. Returning:', JSON.stringify(tools, null, 2)); res.json({ tools }); }); app.post('/v1/chat/completions', async (req, res) => { const request = req.body; const messages = request.messages; // Check if the last message contains tool calls const lastMessage = messages[messages.length - 1]; if (lastMessage.role === 'assistant' && lastMessage.tool_calls) { const results = await (0, handler_1.handleToolCalls)(lastMessage.tool_calls, HUGGINGFACE_API_KEY); return res.json({ id: 'chatcmpl-456', object: 'chat.completion', created: Math.floor(Date.now() / 1000), model: 'hf-mcp-server', choices: [{ index: 0, message: { role: 'assistant', content: 'I\'ve processed your request.', tool_calls: [] }, finish_reason: 'tool_calls' }], tool_responses: results }); } // If we reach here, return a response asking the user to choose a tool res.json({ id: 'chatcmpl-123', object: 'chat.completion', created: Math.floor(Date.now() / 1000), model: 'hf-mcp-server', choices: [{ index: 0, message: { role: 'assistant', tool_calls: [ { id: 'call_abc123', type: 'function', function: { name: 'generate_image', arguments: JSON.stringify({ prompt: 'I need a description from you for the image you\'d like to generate.' }) } } ] }, finish_reason: 'tool_calls' }] }); }); return new Promise((resolve, reject) => { try { app.listen(port, () => { console.log(`HTTP Server running on port ${port}`); resolve(); }); } catch (error) { reject(error); } }); } // For backward compatibility, export startServer as an alias to startHttpServer exports.startServer = startHttpServer;