@react-spa-scaffold/mcp
v2.4.0
Published
MCP server for scaffolding projects based on react-spa-scaffold template
Maintainers
Readme
react-spa-scaffold MCP Server
TL;DR: An MCP server that provides knowledge for AI agents to scaffold React projects. The AI asks what you need, this server provides the info, and the AI generates your project.
3 Tools:
get_features— List available feature modulesget_scaffold— Get dependencies and file structure for selected featuresget_file— Fetch ANY file content (config, docs, source files)
Philosophy
MCP provides knowledge, AI provides execution.
| MCP Server Does | AI Agent Does | | ------------------------ | ---------------------------- | | Lists available features | Decides which to include | | Reports dependencies | Writes package.json | | Provides file content | Adapts for selected features | | Documents conventions | Follows the patterns |
Quick Start
# From monorepo root
npm install && npm run mcp:build
# Test with MCP Inspector
npm run mcp:inspectConfiguration
Add to your MCP client config:
{
"mcpServers": {
"react-spa-scaffold": {
"command": "npx",
"args": ["-y", "@react-spa-scaffold/mcp@latest"]
}
}
}| Client | Config Location |
| -------------- | ----------------------------------------------------------------- |
| Claude Code | .mcp.json (project) or ~/.claude/settings.json (global) |
| Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.json |
| VS Code | .vscode/mcp.json |
Quick Start (Claude Code):
mkdir my-app && cd my-app
echo '{"mcpServers":{"react-spa-scaffold":{"command":"npx","args":["-y","@react-spa-scaffold/mcp@latest"]}}}' > .mcp.jsonOpen in Claude Code and start scaffolding.
For development without publishing:
cd packages/mcp
npm run build
npm link # Makes react-spa-scaffold-mcp available globallyThen use in config:
{
"mcpServers": {
"react-spa-scaffold": {
"command": "react-spa-scaffold-mcp"
}
}
}Or point directly to the built file:
{
"mcpServers": {
"react-spa-scaffold": {
"command": "node",
"args": ["/path/to/packages/mcp/dist/index.js"]
}
}
}Available Features
15 feature modules that can be combined:
| Feature | Description | Required |
| --------------- | --------------------------------------------- | -------- |
| core | React 19 + TypeScript + Vite 7 + Tailwind CSS | Always |
| mobile | Responsive design utilities + viewport hooks | Optional |
| routing | React Router 7 with lazy loading | Optional |
| ui | Shadcn/UI + icons + animations + toasts | Optional |
| theming | Light/dark/system theme (requires state) | Optional |
| forms | React Hook Form + Zod validation | Optional |
| state | Zustand with persistence + theme state | Optional |
| api | TanStack Query + API client | Optional |
| i18n | LinguiJS internationalization | Optional |
| testing | Vitest + Playwright + MSW | Optional |
| performance | React Profiler + Lighthouse + Web Vitals | Optional |
| devtools | ESLint + Prettier + Husky | Optional |
| ci | GitHub Actions + Dependabot | Optional |
| observability | Sentry error tracking | Optional |
| auth | Clerk authentication with modal sign-in | Optional |
Tools
get_features
List all available feature modules.
const result = await client.callTool('get_features', {});
// Returns: { id, name, description, required }[]get_scaffold
Get complete scaffold information for selected features.
const result = await client.callTool('get_scaffold', {
features: ['routing', 'ui', 'forms', 'testing'],
projectName: 'my-app',
});
// Returns: { packageJson, fileStructure, configFiles, docs, setupCommands, instructions }
// Note: All paths are lazy-loaded via get_fileget_file
Fetch content of ANY file from templates.
const result = await client.callTool('get_file', {
path: 'src/App.tsx', // or 'vite.config.ts', 'docs/ARCHITECTURE.md'
});
// Returns: { path, content }Use paths from get_scaffold response:
configFiles: config file pathsdocs: documentation pathsfileStructure: ALL source file paths
IMPORTANT: Fetch content for EVERY file, then strip code for unselected features.
Resources
Documentation resources read from actual files (auto-synced):
| URI | Source | Description |
| --------------------- | ------------------------------------------------- | ------------------------- |
| docs://conventions | CODING_STANDARDS.md + COMPONENT_GUIDELINES.md | Code patterns and naming |
| docs://architecture | ARCHITECTURE.md | Technology stack and flow |
| docs://testing | TESTING.md + E2E_TESTING.md | Unit and E2E testing |
| docs://i18n | INTERNATIONALIZATION.md | LinguiJS setup |
| docs://api | API_REFERENCE.md | API client patterns |
| docs://claude | CLAUDE.md | AI assistant guidance |
Example Workflow
get_features() → choose features → get_scaffold() → get_file() for each path → write projectStep 1: Query features
const features = await mcp.callTool('get_features', {});
// Returns: core, routing, ui, forms, state, api, i18n, testing, devtools, ciStep 2: Get scaffold
const scaffold = await mcp.callTool('get_scaffold', {
features: ['routing', 'ui', 'forms'],
projectName: 'my-app',
});
// Returns: packageJson, fileStructure paths, configFiles paths, docs pathsStep 3: Fetch each file
// Fetch ALL files from fileStructure, configFiles, and docs
const appContent = await mcp.callTool('get_file', { path: 'src/App.tsx' });
const viteConfig = await mcp.callTool('get_file', { path: 'vite.config.ts' });
// ... fetch every file pathStep 4: AI writes project
mkdir my-app && cd my-app
→ Write package.json from scaffold.packageJson
→ Write each file (strip code for unselected features)
→ npm install && npm run buildDevelopment
Scripts
| Command | Description |
| ------------------- | ------------------------ |
| npm run build | Compile TypeScript |
| npm run dev | Watch mode |
| npm start | Run server |
| npm run inspect | Test with MCP Inspector |
| npm run bundle | Bundle templates for npm |
| npm run typecheck | Type check only |
react-spa-scaffold/
├── package.json # Workspaces config
├── src/ # Main react-spa-scaffold app
├── docs/ # Documentation (read by MCP)
├── tests/ # Test files (read by MCP)
└── packages/
└── mcp/
├── src/
│ ├── index.ts # Entry point (STDIO transport)
│ ├── server.ts # MCP server setup
│ ├── features/ # Feature registry and types
│ ├── tools/ # Tool implementations
│ ├── resources/ # MCP resources (docs)
│ └── utils/ # Helpers
├── scripts/
│ └── bundle-templates.js
└── package.jsonThe server supports two modes:
Development mode (monorepo):
- Reads files directly from monorepo root
- Changes reflected immediately
- No bundling needed
Published mode (npx):
- Reads from bundled
templates/directory - Templates copied at publish time via
npm run bundle
// Automatically detects which mode via .bundled marker file
export const isPublishedMode = existsSync(BUNDLE_MARKER);
export const CONTENT_ROOT = isPublishedMode ? BUNDLED_PATH : MONOREPO_ROOT;# prepublishOnly runs bundle + build automatically
npm publishOr manually:
npm run bundle # Copy templates
npm run build # Compile TypeScript
npm publish- Create feature file in
src/features/definitions/my-feature.ts:
import type { Feature } from '../types.js';
export const myFeature: Feature = {
name: 'My Feature',
description: 'Description shown to users',
required: false,
dependencies: ['some-package'],
devDependencies: ['some-dev-package'],
files: ['src/lib/myFeature.ts'],
scripts: { 'my-script': 'some-command' },
};Export from
src/features/definitions/index.tsAdd to
src/features/registry.tsFEATURES objectCreate actual files in react-spa-scaffold's
src/Rebuild:
npm run build
- Add to
src/resources/docs.ts:
'docs://my-topic': {
files: ['docs/MY_TOPIC.md'],
name: 'My Topic',
description: 'Description shown to clients',
},Create
docs/MY_TOPIC.mdRebuild:
npm run build
Resources read files at runtime — content updates without rebuilding.
Troubleshooting
| Problem | Solution |
| ------------------------- | --------------------------------------------------------- |
| "File not found" | Run from monorepo: cd packages/mcp && npm start |
| Tools not appearing | Check config path, run npm run build, check stderr logs |
| Type errors after changes | Run npm run typecheck, then rebuild |
License
MIT
