Skip to main content
Glama

3D-MCP

by team-plask
extract-schemas.ts5.62 kB
import { join } from "path"; import { existsSync, mkdirSync, writeFileSync, readdirSync, rmSync, } from "fs"; import { zodToJsonSchema } from "zod-to-json-schema"; // Import path to the tools directory const TOOLS_DIR = join( process.cwd(), "packages", "src", "tool" ); // Directory to save extracted schemas export const SCHEMA_DIR = join( process.cwd(), "packages", "scripts", "schemas" ); /** * Clean up temporary schema files and directories */ export function cleanupSchemas() { if (existsSync(SCHEMA_DIR)) { console.log( `Cleaning up temporary schema files in ${SCHEMA_DIR}` ); rmSync(SCHEMA_DIR, { recursive: true, force: true }); console.log("Schema files removed"); } } // Ensure schema directory exists function ensureDirectoryExists(dir: string) { if (!existsSync(dir)) { mkdirSync(dir, { recursive: true }); } } /** * Extract schema information for a tool category */ async function extractCategorySchemas( category: string, tools: Record<string, any>, silent: boolean = false ) { if (!silent) console.log(`Extracting schemas for ${category}...`); // Create category directory const categoryDir = join(SCHEMA_DIR, category); ensureDirectoryExists(categoryDir); // Process each tool in the category for (const [toolName, tool] of Object.entries(tools)) { if (!silent) console.log(`Processing ${toolName}...`); try { // Create a unified schema object for the tool const toolSchema: any = { name: toolName, description: tool.description || "", parameters: null, returns: null, }; // Extract and convert parameters schema if (tool.parameters) { const parametersJsonSchema = zodToJsonSchema( tool.parameters, { $refStrategy: "none", errorMessages: true, target: "openApi3", // Include descriptions in the schema } ); toolSchema.parameters = parametersJsonSchema; } // Extract and convert returns schema if (tool.returns) { const returnsJsonSchema = zodToJsonSchema( tool.returns, { $refStrategy: "none", errorMessages: true, target: "openApi3", // Include descriptions in the schema } ); toolSchema.returns = returnsJsonSchema; } // Write the unified schema to a single JSON file writeFileSync( join(categoryDir, `${toolName}.json`), JSON.stringify(toolSchema, null, 2) ); if (!silent) console.log( `Successfully extracted schemas for ${toolName}` ); } catch (err) { console.error( `Error extracting schemas for ${toolName}:`, err ); } } } /** * Discover all domain directories in the tools directory * and dynamically import their atomic tools */ export async function discoverDomains( silent: boolean = false ): Promise<string[]> { if (!existsSync(TOOLS_DIR)) { console.error( `Tools directory not found: ${TOOLS_DIR}` ); return []; } const domains = readdirSync(TOOLS_DIR, { withFileTypes: true, }) .filter((dirent) => dirent.isDirectory()) .map((dirent) => dirent.name); if (!silent) { console.log( `Discovered domains: ${domains.join(", ")}` ); } return domains; } /** * Dynamically import atomic tools for a specific domain */ async function importDomainTools( domain: string, silent: boolean = false ): Promise<Record<string, any>> { try { const atomicPath = `../src/tool/${domain}/atomic`; const module = await import(atomicPath); // Try to get the domain's atomic tools with execute property // Different domains might use different naming conventions const toolsExport = module[`${domain}AtomicToolsWithExecute`] || module[ `${domain.replace(/s$/, "")}AtomicToolsWithExecute` ]; if ( toolsExport && Object.keys(toolsExport).length > 0 ) { if (!silent) { console.log( `Successfully imported atomic tools for ${domain}` ); } return toolsExport; } else { if (!silent) { console.log(`No atomic tools found for ${domain}`); } return {}; } } catch (e) { if (!silent) { console.log( `Could not import atomic tools for ${domain}: ${e}` ); } return {}; } } export async function extractSchemas( silent: boolean = false ) { // Ensure the schema directory exists ensureDirectoryExists(SCHEMA_DIR); // Discover all domains in the tools directory const domains = await discoverDomains(silent); const processedDomains: string[] = []; // Process each domain for (const domain of domains) { // Import tools for this domain const domainTools = await importDomainTools( domain, silent ); // Extract schemas if tools were found if (Object.keys(domainTools).length > 0) { await extractCategorySchemas( domain, domainTools, silent ); processedDomains.push(domain); } } if (!silent && processedDomains.length > 0) { console.log( `Schema extraction completed successfully for domains: ${processedDomains.join( ", " )}` ); } else if (!silent) { console.log( "No domains processed. Check that tool directories contain atomic.ts files." ); } return SCHEMA_DIR; } // Execute directly when this script is run extractSchemas().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/team-plask/3d-mcp'

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