generate_project_starter
Create new projects from templates like fastapi or react-vite by specifying project name and template type to generate starter code structure.
Instructions
Generates a starter project from a template (e.g., 'fastapi', 'react-vite').
Args:
project_name: The name for the new project directory.
template: The project template to use.
Returns:
A summary of the created project structure.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| project_name | Yes | ||
| template | Yes |
Implementation Reference
- MCP tool handler for 'generate_project_starter'. Registers the tool and provides the execution logic, which delegates to the generate_project function from project_generator.py, adds user-friendly summary, and handles errors.async def generate_project_starter(project_name: str, template: str): """ Generates a starter project from a template (e.g., 'fastapi', 'react-vite'). Args: project_name: The name for the new project directory. template: The project template to use. Returns: A summary of the created project structure. """ from .project_generator import generate_project try: result = generate_project(project_name, template) # Provide a more user-friendly summary summary = f"✅ Successfully created '{result['project_name']}' using the '{result['template_used']}' template.\n" summary += f"Location: {result['project_path']}\n\n" summary += "Next steps:\n" if template == "fastapi": summary += f"1. cd {result['project_name']}\n" summary += "2. uv pip sync\n" summary += "3. uv run uvicorn main:app --reload\n" elif template == "react-vite": summary += f"1. cd {result['project_name']}\n" summary += "2. npm install\n" summary += "3. npm run dev\n" result["user_summary"] = summary return result except (ValueError, FileExistsError) as e: return {"error": str(e)}
- Core implementation of project generation. Creates directory structure and files from predefined TEMPLATES based on the selected template (e.g., 'fastapi', 'react-vite'), replaces placeholders, and returns a summary of created items.def generate_project( project_name: str, template_name: str, base_path: str = "." ) -> ProjectCreationSummary: """ Generates a new project from a template. Args: project_name: The name of the new project (will be created as a directory). template_name: The name of the template to use (e.g., 'fastapi'). base_path: The path where the project directory will be created. Returns: A dictionary summarizing the created files and directories. """ if template_name not in TEMPLATES: raise ValueError( f"Template '{template_name}' not found. Available templates: {list(TEMPLATES.keys())}" ) project_path = os.path.join(base_path, project_name) if os.path.exists(project_path): raise FileExistsError(f"Directory '{project_path}' already exists.") os.makedirs(project_path) template = TEMPLATES[template_name] created_files = [] created_dirs = {project_path} for file_path, content in template.items(): # Handle nested directories full_path = os.path.join(project_path, file_path) dir_name = os.path.dirname(full_path) if not os.path.exists(dir_name): os.makedirs(dir_name) created_dirs.add(dir_name) # Replace project name placeholder formatted_content = content.replace("PROJECT_NAME_PLACEHOLDER", project_name) with open(full_path, "w", encoding="utf-8") as f: f.write(formatted_content.strip()) created_files.append(full_path) return { "project_name": project_name, "template_used": template_name, "project_path": project_path, "directories_created": sorted(list(created_dirs)), "files_created": sorted(created_files), }
- Predefined project templates used by generate_project. Contains boilerplate code and configurations for 'fastapi' and 'react-vite' starters, including main app files, package configs, README, gitignore, and tests.TEMPLATES: Dict[str, Dict[str, str]] = { "fastapi": { "main.py": """ from fastapi import FastAPI app = FastAPI( title="My FastAPI Project", description="A new project generated by MCP.", version="0.1.0", ) @app.get("/") async def read_root(): return {"message": "Hello, World!"} @app.get("/items/{item_id}") async def read_item(item_id: int, q: str | None = None): return {"item_id": item_id, "q": q} """, "pyproject.toml": """ [project] name = "PROJECT_NAME_PLACEHOLDER" version = "0.1.0" description = "A new FastAPI project." authors = [{ name = "Your Name", email = "you@example.com" }] requires-python = ">=3.12" dependencies = [ "fastapi", "uvicorn[standard]", ] [project.optional-dependencies] dev = ["pytest"] """, "README.md": """ # PROJECT_NAME_PLACEHOLDER A new FastAPI project generated by Documentation Search Enhanced MCP. ## To run: 1. `uv pip sync` 2. `uv run uvicorn main:app --reload` ## To test: `uv run pytest` """, ".gitignore": """ __pycache__/ *.pyc .env .venv/ dist/ build/ *.egg-info """, "tests/test_main.py": """ from fastapi.testclient import TestClient from main import app client = TestClient(app) def test_read_root(): response = client.get("/") assert response.status_code == 200 assert response.json() == {"message": "Hello, World!"} """, }, "react-vite": { "index.html": """ <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>PROJECT_NAME_PLACEHOLDER</title> </head> <body> <div id="root"></div> <script type="module" src="/src/main.jsx"></script> </body> </html> """, "package.json": """ {{ "name": "PROJECT_NAME_PLACEHOLDER", "private": true, "version": "0.0.0", "type": "module", "scripts": {{ "dev": "vite", "build": "vite build", "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview" }}, "dependencies": {{ "react": "^18.2.0", "react-dom": "^18.2.0" }}, "devDependencies": {{ "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", "@vitejs/plugin-react": "^4.0.3", "eslint": "^8.45.0", "eslint-plugin-react": "^7.32.2", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.3", "vite": "^4.4.5" }} }} """, "vite.config.js": """ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' // https://vitejs.dev/config/ export default defineConfig({ plugins: [react()], }) """, ".gitignore": """ # Logs logs *.log # Runtime data pids *.pid *.seed *.pid.lock # Dependency directories node_modules/ dist/ # IDE files .idea/ .vscode/ # Environment variables .env .env.local """, "src/App.jsx": """ import './App.css' function App() { return ( <> <h1>PROJECT_NAME_PLACEHOLDER</h1> <p className="read-the-docs"> React + Vite project generated by MCP. </p> </> ) } export default App """, "src/main.jsx": """ import React from 'react' import ReactDOM from 'react-dom/client' import App from './App.jsx' import './index.css' ReactDOM.createRoot(document.getElementById('root')).render( <React.StrictMode> <App /> </React.StrictMode>, ) """, "src/index.css": """ :root { font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; } """, "src/App.css": """ #root { max-width: 1280px; margin: 0 auto; padding: 2rem; text-align: center; } """, }, }