download-template
Download pre-configured starter templates for React or Next.js projects to initialize new InsForge applications with backend services.
Instructions
CRITICAL: MANDATORY FIRST STEP for all new InsForge projects. Download pre-configured starter template to a temporary directory. After download, you MUST copy files to current directory using the provided command.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| frame | Yes | Framework to use for the template (support React and Next.js) | |
| projectName | No | Name for the project directory (optional, defaults to "insforge-react") |
Implementation Reference
- src/shared/tools.ts:515-597 (handler)The core handler logic for the 'download-template' tool. Fetches an anonymous API key, creates a temporary directory, executes 'npx create-insforge-app' to download the starter template, and returns instructions for copying files to the current project directory.withUsageTracking('download-template', async ({ frame, projectName }) => { try { // Get the anon key from backend const response = await fetch(`${API_BASE_URL}/api/auth/tokens/anon`, { method: 'POST', headers: { 'x-api-key': getApiKey(), 'Content-Type': 'application/json', }, }); const result = await handleApiResponse(response); const anonKey = result.accessToken; if (!anonKey) { throw new Error('Failed to retrieve anon key from backend'); } // Create temp directory for download const tempDir = tmpdir(); const targetDir = projectName || `insforge-${frame}`; const templatePath = `${tempDir}/${targetDir}`; console.error(`[download-template] Target path: ${templatePath}`); // Check if template already exists in temp, remove it first try { const stats = await fs.stat(templatePath); if (stats.isDirectory()) { console.error(`[download-template] Removing existing template at ${templatePath}`); await fs.rm(templatePath, { recursive: true, force: true }); } } catch { // Directory doesn't exist, which is fine } const command = `npx create-insforge-app ${targetDir} --frame ${frame} --base-url ${API_BASE_URL} --anon-key ${anonKey} --skip-install`; // Execute the npx command in temp directory const { stdout, stderr } = await execAsync(command, { maxBuffer: 10 * 1024 * 1024, // 10MB buffer cwd: tempDir, }); // Check if command was successful (basic validation) const output = stdout || stderr || ''; if (output.toLowerCase().includes('error') && !output.includes('successfully')) { throw new Error(`Failed to download template: ${output}`); } return await addBackgroundContext({ content: [ { type: 'text', text: `ā React template downloaded successfully š Template Location: ${templatePath} ā ļø IMPORTANT: The template is in a temporary directory and NOT in your current working directory. š“ CRITICAL NEXT STEP REQUIRED: You MUST copy ALL files (INCLUDING HIDDEN FILES like .env, .gitignore, etc.) from the temporary directory to your current project directory. Copy all files from: ${templatePath} To: Your current project directory `, }, ], }); } catch (error) { const errMsg = error instanceof Error ? error.message : 'Unknown error occurred'; return { content: [ { type: 'text', text: `Error downloading template: ${errMsg}`, }, ], isError: true, }; } }) );
- src/shared/tools.ts:506-514 (schema)Input schema parameters for the download-template tool: 'frame' (required, enum react/nextjs) and 'projectName' (optional string).{ frame: z .enum(['react', 'nextjs']) .describe('Framework to use for the template (support React and Next.js)'), projectName: z .string() .optional() .describe('Name for the project directory (optional, defaults to "insforge-react")'), },
- src/shared/tools.ts:503-597 (registration)Registration of the 'download-template' tool on the MCP server within the registerInsforgeTools function, including name, description, schema, and handler.server.tool( 'download-template', 'CRITICAL: MANDATORY FIRST STEP for all new InsForge projects. Download pre-configured starter template to a temporary directory. After download, you MUST copy files to current directory using the provided command.', { frame: z .enum(['react', 'nextjs']) .describe('Framework to use for the template (support React and Next.js)'), projectName: z .string() .optional() .describe('Name for the project directory (optional, defaults to "insforge-react")'), }, withUsageTracking('download-template', async ({ frame, projectName }) => { try { // Get the anon key from backend const response = await fetch(`${API_BASE_URL}/api/auth/tokens/anon`, { method: 'POST', headers: { 'x-api-key': getApiKey(), 'Content-Type': 'application/json', }, }); const result = await handleApiResponse(response); const anonKey = result.accessToken; if (!anonKey) { throw new Error('Failed to retrieve anon key from backend'); } // Create temp directory for download const tempDir = tmpdir(); const targetDir = projectName || `insforge-${frame}`; const templatePath = `${tempDir}/${targetDir}`; console.error(`[download-template] Target path: ${templatePath}`); // Check if template already exists in temp, remove it first try { const stats = await fs.stat(templatePath); if (stats.isDirectory()) { console.error(`[download-template] Removing existing template at ${templatePath}`); await fs.rm(templatePath, { recursive: true, force: true }); } } catch { // Directory doesn't exist, which is fine } const command = `npx create-insforge-app ${targetDir} --frame ${frame} --base-url ${API_BASE_URL} --anon-key ${anonKey} --skip-install`; // Execute the npx command in temp directory const { stdout, stderr } = await execAsync(command, { maxBuffer: 10 * 1024 * 1024, // 10MB buffer cwd: tempDir, }); // Check if command was successful (basic validation) const output = stdout || stderr || ''; if (output.toLowerCase().includes('error') && !output.includes('successfully')) { throw new Error(`Failed to download template: ${output}`); } return await addBackgroundContext({ content: [ { type: 'text', text: `ā React template downloaded successfully š Template Location: ${templatePath} ā ļø IMPORTANT: The template is in a temporary directory and NOT in your current working directory. š“ CRITICAL NEXT STEP REQUIRED: You MUST copy ALL files (INCLUDING HIDDEN FILES like .env, .gitignore, etc.) from the temporary directory to your current project directory. Copy all files from: ${templatePath} To: Your current project directory `, }, ], }); } catch (error) { const errMsg = error instanceof Error ? error.message : 'Unknown error occurred'; return { content: [ { type: 'text', text: `Error downloading template: ${errMsg}`, }, ], isError: true, }; } }) );