Skip to main content
Glama

3D-MCP

by team-plask
plugin-codegen.ts5.75 kB
import { join } from "path"; import { existsSync, readFileSync, readdirSync, rmSync, writeFileSync, } from "fs"; import { extractSchemas, SCHEMA_DIR, cleanupSchemas, } from "./extract-schemas"; import { PLUGINS } from "./config/pluginsConfig"; import { type IGenerator } from "./generators/IGenerator"; import { PythonGenerator } from "./generators/python-generator"; import { UnrealGenerator } from "./generators/unreal-generator"; import { ensureDirectoryExists } from "./utils/fs"; // ============================================================================ // Generators Map // ============================================================================ /** * Map of language to generator instance */ const generatorMap: Record<string, IGenerator> = { python: new PythonGenerator(), cpp: new UnrealGenerator(), }; // ============================================================================ // Helper Functions // ============================================================================ /** * Load tool definitions from the extracted schema files */ function loadToolDefinitions(category: string): { name: string; description: string; parameters: any; returns: any; }[] { const toolDir = join(SCHEMA_DIR, category); if (!existsSync(toolDir)) { console.warn( `Schema directory not found for ${category}. Run extract-schemas.ts first.` ); return []; } const files = readdirSync(toolDir); const tools = []; for (const file of files) { // Only process JSON files if (!file.endsWith(".json")) continue; try { // Load and parse the unified schema file const toolSchema = JSON.parse( readFileSync(join(toolDir, file), "utf8") ); tools.push({ name: toolSchema.name, description: toolSchema.description || "", parameters: toolSchema.parameters, returns: toolSchema.returns, }); } catch (err) { console.warn( `Could not parse schema for ${file}: ${err}` ); } } return tools; } /** * Get all available tool categories by scanning the schema directory */ function getAvailableCategories(): string[] { if (!existsSync(SCHEMA_DIR)) { return []; } return readdirSync(SCHEMA_DIR, { withFileTypes: true }) .filter((dirent) => dirent.isDirectory()) .map((dirent) => dirent.name); } // ============================================================================ // Main Function and Execution // ============================================================================ export async function generatePluginCode( temporarySchemas: boolean = true ) { console.log("Starting plugin code generation..."); // Generate schemas if not already present or always if temporary if (temporarySchemas || !existsSync(SCHEMA_DIR)) { console.log("Extracting schemas..."); // Use silent mode to avoid duplicate logs await extractSchemas(true); console.log("Schemas extracted successfully"); } // Get all tool categories by scanning the schema directory const toolCategories = getAvailableCategories(); if (toolCategories.length === 0) { console.error( "No tool categories found! Check schema extraction process." ); return; } console.log( `Found tool categories: ${toolCategories.join(", ")}` ); // Add plugin directories to .gitignore if they don't exist try { const gitignorePath = join(process.cwd(), ".gitignore"); if (existsSync(gitignorePath)) { let gitignore = readFileSync(gitignorePath, "utf8"); if (!gitignore.includes("packages/plugins/")) { gitignore += "\n# Generated plugin code\npackages/plugins/\n"; writeFileSync(gitignorePath, gitignore); console.log( "Added packages/plugins/ to .gitignore" ); } } } catch (err) { console.warn("Could not update .gitignore:", err); } // Process each tool category for (const category of toolCategories) { // Load tools from the extracted schema files const tools = loadToolDefinitions(category); if (tools.length === 0) { console.log(`No tool schemas found for ${category}`); continue; } // Generate implementations for each plugin for (const plugin of PLUGINS) { const pluginCategoryDir = join( process.cwd(), "packages", plugin.dir, category ); ensureDirectoryExists(pluginCategoryDir); try { // Get the appropriate generator based on plugin language const generator = generatorMap[plugin.lang]; if (!generator) { console.warn( `No generator available for ${plugin.lang}. Skipping ${plugin.name}` ); continue; } // Generate implementation for this plugin and category generator.generateImplementation( plugin, category, tools ); } catch (err) { console.error( `Error generating ${plugin.name} implementation for ${category}:`, err ); } } } // Generate server components for each plugin for (const plugin of PLUGINS) { try { const generator = generatorMap[ plugin.lang ] as PythonGenerator; generator.generateServer(plugin, toolCategories); } catch (err) { console.error( `Error generating server for ${plugin.name}:`, err ); } } // Clean up temporary schema files if requested if (temporarySchemas) { cleanupSchemas(); } } // Execute the main function directly generatePluginCode(true).catch((err) => { console.error("Code generation failed:", err); process.exit(1); });

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/team-plask/3d-mcp'

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