Skip to main content
Glama
templates.ts4.55 kB
import { z } from "zod"; import fs from "fs/promises"; import path from "path"; /** * Template Tools - Access static code templates */ // ============================================ // Get Template Tool // ============================================ export const getTemplateSchema = { name: "get_template", description: "Retrieves a specific code template from the library", inputSchema: z.object({ category: z .enum([ "auth", "configs", "database", "discord-bot", "django", "express", "fastapi", "go", "graphql", "hono", "interaction", "mobile", "nestjs", "nextjs", "react", "rust", "svelte", "testing", "trpc", "vue", "websocket", "infrastructure", "ci-cd", "cloud", "api", "workflows", ]) .describe("Template category"), templateName: z .string() .optional() .describe("Specific template file name (lists available if empty)"), }), }; export async function getTemplateHandler(args: { category: string; templateName?: string; }) { const { category, templateName } = args; // In a real deployed environment, we need to know where the templates are. // Assuming they are copied to dist/data/templates or src/data/templates is accessible. // For this environment: const basePath = path.join(process.cwd(), "src", "data", "templates"); const categoryPath = path.join(basePath, category); try { // Check if category exists try { await fs.access(categoryPath); } catch { return { content: [ { type: "text", text: `Category '${category}' not found. Available categories: auth, database, react, vue, etc.`, }, ], isError: true, }; } // If no template name, list files if (!templateName) { const files = await fs.readdir(categoryPath); return { content: [ { type: "text", text: `# Templates in '${category}'\n\n${files.map((f) => `- ${f}`).join("\n")}\n\nUsage: get_template(category: "${category}", templateName: "${files[0]}")`, }, ], }; } // Search for file (fuzzy match or direct) // We'll search recursively for the file if it's not in the root of the category async function findFile(dir: string, name: string): Promise<string | null> { const entries = await fs.readdir(dir, { withFileTypes: true }); // Direct match const match = entries.find( (e) => e.name === name || e.name === name + ".md" || e.name === name + ".ts" || e.name === name + ".js", ); if (match && match.isFile()) return path.join(dir, match.name); // Fuzzy match (contains) const fuzzy = entries.find((e) => e.isFile() && e.name.includes(name)); if (fuzzy) return path.join(dir, fuzzy.name); // Recursive search for (const entry of entries) { if (entry.isDirectory()) { const found = await findFile(path.join(dir, entry.name), name); if (found) return found; } } return null; } const filePath = await findFile(categoryPath, templateName); if (!filePath) { return { content: [ { type: "text", text: `Template '${templateName}' not found in category '${category}'.`, }, ], isError: true, }; } const content = await fs.readFile(filePath, "utf-8"); // If it's a markdown file, it likely already contains formatted code/docs if (filePath.endsWith(".md")) { return { content: [ { type: "text", text: `# Template: ${category}/${path.basename(filePath)}\n\n${content}`, }, ], }; } // For code files, wrap in code block return { content: [ { type: "text", text: `# Template: ${category}/${path.basename(filePath)}\n\n\`\`\`${path.extname(filePath).slice(1) || "text"}\n${content}\n\`\`\``, }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error accessing templates: ${(error as Error).message}`, }, ], isError: true, }; } } export const templateTools = { getTemplateSchema, getTemplateHandler, };

Latest Blog Posts

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/millsydotdev/Code-MCP'

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