Skip to main content
Glama

3D Asset Processing MCP

by GeoLibra
server.ts4.23 kB
#!/usr/bin/env node import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema, Tool, } from '@modelcontextprotocol/sdk/types.js'; import { allTools } from './tools/index'; import logger from './utils/logger'; import { globalCache } from './utils/cache'; import { globalFileHandler } from './utils/file-handler'; import { version } from '../package.json'; class AssetProcessingMCPServer { private server: Server; constructor() { this.server = new Server( { name: '3d-asset-processing-mcp', version: version, } ); this.setupHandlers(); this.setupErrorHandling(); } private setupHandlers() { // List available tools this.server.setRequestHandler(ListToolsRequestSchema, async () => { const tools: Tool[] = allTools.map(tool => ({ name: tool.name, description: tool.description, inputSchema: tool.inputSchema, })); return { tools }; }); // Execute tool call this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; logger.info(`Tool called: ${name}`, { args }); // Find the corresponding tool const tool = allTools.find(t => t.name === name); if (!tool) { throw new Error(`Unknown tool: ${name}`); } try { // Execute the tool const result = await tool.execute(args || {}); logger.info(`Tool ${name} completed`, { success: result.success, processingTime: result.metrics?.processingTime }); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } catch (error) { logger.error(`Tool ${name} failed:`, error); return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: error instanceof Error ? error.message : String(error), stack: process.env.NODE_ENV === 'development' && error instanceof Error ? error.stack : undefined }, null, 2), }, ], isError: true, }; } }); } private setupErrorHandling() { // Global error handling process.on('uncaughtException', (error) => { logger.error('Uncaught exception:', error); process.exit(1); }); process.on('unhandledRejection', (reason, promise) => { logger.error('Unhandled rejection at:', promise, 'reason:', reason); process.exit(1); }); // Graceful shutdown process.on('SIGINT', async () => { logger.info('Received SIGINT, shutting down gracefully...'); await this.cleanup(); process.exit(0); }); process.on('SIGTERM', async () => { logger.info('Received SIGTERM, shutting down gracefully...'); await this.cleanup(); process.exit(0); }); } private async cleanup() { try { // Clear cache globalCache.flush(); // Clean up temporary files await globalFileHandler.cleanupAll(); logger.info('Cleanup completed'); } catch (error) { logger.error('Cleanup failed:', error); } } async run() { // Ensure necessary directories exist await globalFileHandler.ensureDir('./temp'); await globalFileHandler.ensureDir('./logs'); const transport = new StdioServerTransport(); await this.server.connect(transport); // Log to file only, not to console to avoid interfering with MCP JSON-RPC protocol logger.info('3D Asset Processing MCP Server v' + version + ' started'); logger.info(`Available tools: ${allTools.map(t => t.name).join(', ')}`); logger.info('Server ready for connections...'); } } if (require.main === module) { const server = new AssetProcessingMCPServer(); server.run().catch((error) => { logger.error('Failed to start server:', error); process.exit(1); }); } export default AssetProcessingMCPServer;

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/GeoLibra/3d-asset-processing-mcp'

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