Skip to main content
Glama

OpenRouter MCP Multimodal Server

by hoangdn3
index.ts3.62 kB
#!/usr/bin/env node // OpenRouter Multimodal MCP Server import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { ToolHandlers } from './tool-handlers.js'; // Define the default model to use when none is specified const DEFAULT_MODEL = 'qwen/qwen2.5-vl-32b-instruct'; interface ServerOptions { apiKey?: string; defaultModel?: string; } class OpenRouterMultimodalServer { private server: Server; private toolHandlers!: ToolHandlers; // Using definite assignment assertion constructor(options?: ServerOptions) { // Retrieve API key from options or environment variables const apiKey = options?.apiKey || process.env.OPENROUTER_API_KEY; const defaultModel = options?.defaultModel || process.env.OPENROUTER_DEFAULT_MODEL || DEFAULT_MODEL; // Check if API key is provided if (!apiKey) { throw new Error('OpenRouter API key is required. Provide it via options or OPENROUTER_API_KEY environment variable'); } // Initialize the server this.server = new Server( { name: 'openrouter-multimodal-server', version: '1.0.0', }, { capabilities: { tools: {}, }, } ); // Set up error handling this.server.onerror = (error) => console.error('[MCP Error]', error); // Initialize tool handlers this.toolHandlers = new ToolHandlers( this.server, apiKey, defaultModel ); process.on('SIGINT', async () => { await this.server.close(); process.exit(0); }); } async run() { const transport = new StdioServerTransport(); await this.server.connect(transport); console.error('OpenRouter Multimodal MCP server running on stdio'); // Log model information const modelDisplay = this.toolHandlers.getDefaultModel() || DEFAULT_MODEL; console.error(`Using default model: ${modelDisplay}`); console.error('Server is ready to process tool calls. Waiting for input...'); } } // Get MCP configuration if provided let mcpOptions: ServerOptions | undefined; // Check if we're being run as an MCP server with configuration if (process.argv.length > 2) { try { const configArg = process.argv.find(arg => arg.startsWith('--config=')); if (configArg) { const configPath = configArg.split('=')[1]; const configData = require(configPath); // Extract configuration mcpOptions = { apiKey: configData.OPENROUTER_API_KEY || configData.apiKey, defaultModel: configData.OPENROUTER_DEFAULT_MODEL || configData.defaultModel }; if (mcpOptions.apiKey) { console.error('Using API key from MCP configuration'); } } } catch (error) { console.error('Error parsing MCP configuration:', error); } } // Attempt to parse JSON from stdin to check for MCP server parameters if (!mcpOptions?.apiKey) { process.stdin.once('data', (data) => { try { const firstMessage = JSON.parse(data.toString()); if (firstMessage.params && typeof firstMessage.params === 'object') { mcpOptions = { apiKey: firstMessage.params.OPENROUTER_API_KEY || firstMessage.params.apiKey, defaultModel: firstMessage.params.OPENROUTER_DEFAULT_MODEL || firstMessage.params.defaultModel }; } } catch (error) { // Not a valid JSON message or no parameters, continue with environment variables } }); } const server = new OpenRouterMultimodalServer(mcpOptions); server.run().catch(console.error);

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/hoangdn3/mcp-ocr-fallback'

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