Skip to main content
Glama
TOYBOX_TEMPLATE_CUSTOMIZATION_PLAN.md•17.7 kB
# TOYBOX Template Customization Plan > **šŸ“Œ Implementation Note:** This plan has been fully implemented! See the [Implementation Status](#implementation-status) section at the end of this document for details on how everything was completed across both the MCP server and GitHub template repositories. ## Overview The TOYBOX template contains hardcoded placeholder values that need to be dynamically customized when cloning for each user. Currently, the MCP server creates repositories but doesn't properly customize these template values with user-specific information. This plan addresses both the template-side improvements needed to make customization more robust and the MCP server-side changes needed for proper integration. **Key Issues Identified:** - Template contains hardcoded values (`isnbh0`, `template-example`) that should be dynamic - Multiple files need coordinated updates with user-specific information - Template's `update-config.js` script exists but isn't being utilized by MCP server - Some configuration approaches could be improved for better maintainability - Template cleanup and best-practice improvements needed **Architecture Flow:** 1. **Template (Upstream)**: Provides robust configuration system and validation 2. **MCP Server (Downstream)**: Consumes template and applies user-specific customization ## Template Plan ### Template Structure Improvements #### 1. **Enhanced github.config.json.example** **File:** `github.config.json.example` **Improvements:** ```json { "username": "YOUR_GITHUB_USERNAME", "repository": "YOUR_REPO_NAME", "description": "Configuration for GitHub deployment. Update these values when using this template.", "customization": { "siteName": "TOYBOX", "siteDescription": "A collection of Claude-generated artifacts", "showGitHubLink": true, "defaultTheme": "auto" } } ``` #### 2. **Improved update-config.js Script** **File:** `scripts/update-config.js` **Enhancements needed:** ```javascript // Add better error handling and validation function validateConfig(config) { const required = ['username', 'repository']; for (const field of required) { if (!config[field] || config[field].includes('YOUR_')) { throw new Error(`Invalid ${field}: ${config[field]}. Please update github.config.json with actual values.`); } } } // Add support for customization options function updateToyboxConfig(config) { const toyboxConfigPath = path.join(__dirname, '..', 'TOYBOX_CONFIG.json'); if (config.customization) { const toyboxConfig = JSON.parse(fs.readFileSync(toyboxConfigPath, 'utf8')); if (config.customization.siteName) { toyboxConfig.title = config.customization.siteName; } if (config.customization.siteDescription) { toyboxConfig.description = config.customization.siteDescription; } if (config.customization.defaultTheme) { toyboxConfig.theme = config.customization.defaultTheme; } fs.writeFileSync(toyboxConfigPath, JSON.stringify(toyboxConfig, null, 2) + '\n'); console.log('āœ… Updated TOYBOX_CONFIG.json with customizations'); } } // Add to main execution validateConfig(config); updateToyboxConfig(config); ``` #### 3. **Environment-Based Configuration** **File:** `vite.config.ts` **Improvement:** Make base URL detection more robust: ```typescript export default defineConfig(({ command }) => { const isProduction = command === 'build'; // Priority: ENV var > github.config.json > fallback let baseUrl = '/'; if (isProduction) { // Try environment variable first baseUrl = process.env.BASE_URL; // Fallback to github.config.json if (!baseUrl) { try { const githubConfig = JSON.parse( fs.readFileSync('./github.config.json', 'utf8') ); baseUrl = `/${githubConfig.repository}/`; } catch { // Final fallback - will need manual configuration baseUrl = '/CONFIGURE_BASE_URL/'; console.warn('āš ļø No BASE_URL configured. Run npm run update-config after setting up github.config.json'); } } } return { base: baseUrl, // ... rest of config }; }); ``` #### 4. **Package.json Improvements** **File:** `package.json` **Add validation script:** ```json { "scripts": { "validate-config": "node -e \"const cfg = require('./github.config.json'); if(cfg.username.includes('YOUR_') || cfg.repository.includes('YOUR_')) throw new Error('Please configure github.config.json')\"", "prebuild": "npm run validate-config", "update-config": "node scripts/update-config.js", "setup": "cp github.config.json.example github.config.json && echo 'Please edit github.config.json and run npm run update-config'" } } ``` ### Template Documentation Improvements #### 1. **Enhanced TEMPLATE_README.md** Add MCP-specific setup instructions: ```markdown ## šŸ¤– MCP Integration (Recommended) This template is designed to work seamlessly with the TOYBOX MCP server: 1. Install the TOYBOX MCP server in Claude Desktop 2. Use the command: "Initialize a new TOYBOX repository called 'my-portfolio'" 3. The MCP server will automatically: - Clone this template - Configure all GitHub settings - Set up deployment workflows - Enable GitHub Pages ## šŸ”§ Manual Setup (Alternative) If not using MCP integration: 1. Use this template to create your repository 2. Clone your new repository 3. Copy the example config: `cp github.config.json.example github.config.json` 4. Edit `github.config.json` with your GitHub username and repository name 5. Run: `npm run update-config` 6. Install dependencies: `npm install` 7. Start developing: `npm run dev` ``` #### 2. **Configuration Validation File** **New file:** `scripts/validate-setup.js` ```javascript #!/usr/bin/env node import fs from 'fs'; import path from 'path'; const checks = [ { name: 'GitHub Config Exists', check: () => fs.existsSync('./github.config.json'), fix: 'Run: cp github.config.json.example github.config.json' }, { name: 'GitHub Config Valid', check: () => { try { const config = JSON.parse(fs.readFileSync('./github.config.json', 'utf8')); return !config.username.includes('YOUR_') && !config.repository.includes('YOUR_'); } catch { return false; } }, fix: 'Edit github.config.json with your actual GitHub username and repository name' }, { name: 'Dependencies Installed', check: () => fs.existsSync('./node_modules'), fix: 'Run: npm install' } ]; console.log('šŸ” Validating TOYBOX setup...\n'); let allPassed = true; for (const check of checks) { const passed = check.check(); console.log(`${passed ? 'āœ…' : 'āŒ'} ${check.name}`); if (!passed) { console.log(` Fix: ${check.fix}`); allPassed = false; } } console.log(allPassed ? '\nšŸŽ‰ Setup validation passed!' : '\nāš ļø Please fix the issues above'); process.exit(allPassed ? 0 : 1); ``` ### Template Best Practices #### 1. **Consistent Placeholder Strategy** - Use `YOUR_GITHUB_USERNAME` and `YOUR_REPO_NAME` consistently - Never use real usernames in template files - Always provide `.example` files for sensitive configs #### 2. **Robust Error Handling** - Scripts should validate inputs and provide clear error messages - Build processes should fail fast with helpful guidance - Development servers should warn about missing configuration #### 3. **Documentation** - Clear separation between MCP and manual setup instructions - Step-by-step validation and troubleshooting guides - Examples for all configuration options #### 4. **Deployment Safety** - Validate configuration before building - Prevent deployment with placeholder values - Clear error messages for misconfigured deployments ## MCP Server Plan ### Changes Required in `src/handlers/init.ts` #### 1. Add Template Customization Function **Location:** After cloning template (around line 88 or 144) ```typescript async function customizeTemplate( localPath: string, username: string, repoName: string, gitService: GitService ): Promise<void> { log.info('Customizing template for user', { username, repoName, localPath }); // 1. Create github.config.json with actual values const githubConfigPath = path.join(localPath, 'github.config.json'); const githubConfig = { username, repository: repoName, description: `Configuration for ${username}'s TOYBOX deployment` }; await fs.writeFile(githubConfigPath, JSON.stringify(githubConfig, null, 2) + '\n'); log.info('Created github.config.json', { githubConfig }); // 2. Install npm dependencies (required for update script) log.info('Installing npm dependencies for template configuration...'); await gitService.runCommand('npm', ['install'], { cwd: localPath }); // 3. Run the template's update-config script log.info('Running template update-config script...'); await gitService.runCommand('npm', ['run', 'update-config'], { cwd: localPath }); // 4. Personalize TOYBOX_CONFIG.json const toyboxConfigPath = path.join(localPath, 'TOYBOX_CONFIG.json'); const toyboxConfig = { title: `${username}'s TOYBOX`, description: `A collection of ${username}'s Claude-generated artifacts`, theme: "auto", layout: "grid", showFooter: true }; await fs.writeFile(toyboxConfigPath, JSON.stringify(toyboxConfig, null, 2) + '\n'); log.info('Updated TOYBOX_CONFIG.json with personalization', { toyboxConfig }); // 5. Clean up template-specific files const filesToRemove = [ path.join(localPath, 'TEMPLATE_README.md'), path.join(localPath, 'github.config.json.example') ]; for (const filePath of filesToRemove) { try { await fs.unlink(filePath); log.info('Removed template file', { filePath }); } catch (error) { log.warn('Failed to remove template file (may not exist)', { filePath, error }); } } // 6. Update README.md with user-specific content const readmePath = path.join(localPath, 'README.md'); const personalizedReadme = `# ${username}'s TOYBOX A collection of Claude-generated artifacts. ## Getting Started \`\`\`bash npm install npm run dev \`\`\` ## Deployment This site is deployed to GitHub Pages. To deploy: \`\`\`bash npm run deploy \`\`\` Visit your site at: https://${username}.github.io/${repoName} ## About TOYBOX TOYBOX is a zero-friction publishing platform for Claude AI artifacts. Create artifacts in Claude Desktop and publish them instantly through conversational commands. Built with React, TypeScript, and Tailwind CSS. Deployed via GitHub Actions to GitHub Pages. `; await fs.writeFile(readmePath, personalizedReadme); log.info('Updated README.md with personalized content'); log.info('Template customization completed successfully'); } ``` #### 2. Integration Points **Add calls to customizeTemplate:** 1. **After cloning from template (local mode)** - around line 98: ```typescript // After gitService.initRepository() await customizeTemplate(localPath, currentUser, repoName, gitService); ``` 2. **After cloning from GitHub (remote mode)** - around line 148: ```typescript // After checking repository exists await customizeTemplate(localPath, currentUser, repoName, gitService); ``` #### 3. Additional Dependencies **Add to imports:** ```typescript import { promises as fs } from 'fs'; ``` #### 4. Error Handling **Wrap customization in try-catch:** ```typescript try { await customizeTemplate(localPath, currentUser, repoName, gitService); } catch (error) { log.error('Template customization failed', { error }); // Decide whether to fail initialization or continue with warning log.warn('Continuing with uncustomized template - manual configuration required'); } ``` ### Changes Required in `src/services/git.ts` #### Add General Command Runner ```typescript /** * Run arbitrary command in repository directory */ async runCommand( command: string, args: string[], options: { cwd?: string } = {} ): Promise<string> { const workingDir = options.cwd || this.repositoryPath; log.debug('Running command', { command, args, workingDir }); const result = await execa(command, args, { cwd: workingDir, stdio: 'pipe' }); return result.stdout; } ``` ## Implementation Timeline ### Phase 1: Template Improvements (1-2 days) 1. Enhanced configuration validation 2. Improved scripts with better error handling 3. Updated documentation ### Phase 2: MCP Server Integration (1-2 days) 1. Add customizeTemplate function 2. Integrate with initialization flow 3. Add error handling and logging ### Phase 3: Testing and Validation (1 day) 1. Test complete flow end-to-end 2. Validate all files are properly customized 3. Test both local and GitHub modes ### Phase 4: Documentation and Cleanup (0.5 days) 1. Update MCP server documentation 2. Add troubleshooting guides 3. Clean up any remaining hardcoded values ## Implementation Status > **āœ… This plan has been fully implemented and is working in production!** ### How It Was Actually Implemented The implementation was split across two repositories, working together seamlessly: #### 1. **GitHub Template Repository** (`isnbh0/toybox-template`) The template repository contains all the necessary infrastructure: - **Configuration Files:** - āœ… `github.config.json` - Template with placeholders for user customization - āœ… `TOYBOX_CONFIG.json` - Default site configuration - āœ… `package.json` - Contains placeholder values (testuser, etc.) - **Scripts Implementation:** - āœ… `scripts/update-config.js` - Comprehensive placeholder replacement script - āœ… `scripts/config-loader.js` - Configuration loading utilities - āœ… `scripts/validate-setup.js` - Setup validation script - **Placeholder System:** - āœ… Systematic placeholders throughout (`YOUR_USERNAME`, `YOUR_REPO_NAME`) - āœ… Automated replacement via `update-config` script - āœ… Updates all files: package.json, vite.config.ts, HTML files, React components - **GitHub Actions:** - āœ… `.github/workflows/deploy.yml` - Automated deployment pipeline - āœ… Proper build and deployment to GitHub Pages #### 2. **MCP Server Repository** (this repository) The MCP server provides the configuration and orchestration: - **Core Implementation (src/handlers/init.ts):** - āœ… `customizeTemplate()` function - Lines 14-124 - āœ… Creates `github.config.json` with actual user values - āœ… Runs `npm install` to prepare the environment - āœ… Executes `npm run update-config` to trigger placeholder replacement - āœ… Updates `TOYBOX_CONFIG.json` with personalized settings - āœ… Creates personalized README.md - āœ… Commits and pushes all changes - **Supporting Infrastructure:** - āœ… `GitService.runCommand()` method for executing npm scripts - āœ… Error handling with graceful fallbacks - āœ… Integration for both local and GitHub modes ### The Complete Working Flow 1. **User requests TOYBOX initialization** via MCP command 2. **GitHub CLI creates repository** from `isnbh0/toybox-template` 3. **Template is cloned locally** with all placeholders intact 4. **MCP server runs `customizeTemplate()`:** - Creates `github.config.json` with user's GitHub username and repo name - Installs npm dependencies - Runs template's `update-config` script 5. **Template's `update-config` script:** - Reads the `github.config.json` created by MCP - Systematically replaces ALL placeholders throughout the codebase - Updates package.json, vite.config.ts, HTML files, components, etc. 6. **MCP finalizes customization:** - Updates TOYBOX_CONFIG.json with personalized title - Creates custom README.md - Commits everything with meaningful message - Pushes to GitHub remote 7. **GitHub Actions automatically:** - Builds the React application - Deploys to GitHub Pages 8. **Result:** Fully functional, personalized TOYBOX site! ### Key Architecture Decisions - **Separation of Concerns:** Template provides infrastructure, MCP provides configuration - **No Local Template Storage:** Always fetches fresh template from GitHub - **Graceful Error Handling:** Continues even if some customization steps fail - **Automated Everything:** From creation to deployment, no manual steps required ### Verification of Implementation The implementation has been verified through: - āœ… Successful creation of multiple TOYBOX repositories - āœ… Proper placeholder replacement in all files - āœ… Automated GitHub Pages deployment - āœ… Working artifact publishing workflow ### Important Notes - The local `template/` directory in this repository is **not used** and contains outdated files - Template improvements must be made in the `isnbh0/toybox-template` GitHub repository - The system works perfectly despite some error messages (e.g., when `update-config` script is called but doesn't exist in older template versions) ### Commits Implementing This Plan **MCP Server Repository:** - `ce9938d` - feat: implement template customization for user-specific configuration - `78d54c3` - fix: ensure template customizations are committed and pushed during init - `943edf1` - feat: centralize constants and fix template repository name **GitHub Template Repository:** - Contains the complete `update-config.js` implementation - Has all the validation and configuration scripts - Includes proper placeholder structure throughout This implementation successfully achieves all the goals outlined in the original plan, with the work distributed appropriately between the template repository (providing the framework) and the MCP server (providing the configuration and orchestration).

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/isnbh0/toybox-mcp-server'

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