create-better-t-stack 2.35.4 → 2.35.5-canary.869063df

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -45,6 +45,40 @@ Follow the prompts to configure your project or use the `--yes` flag for default
45
45
  | **Examples** | • Todo app<br>• AI Chat interface (using Vercel AI SDK) |
46
46
  | **Developer Experience** | • Automatic Git initialization<br>• Package manager choice (npm, pnpm, bun)<br>• Automatic dependency installation |
47
47
 
48
+ ## MCP (Model Context Protocol) Support
49
+
50
+ The CLI now supports the Model Context Protocol, allowing AI assistants to scaffold projects programmatically. This enables seamless integration with AI coding assistants like Claude, Cursor, and others.
51
+
52
+ ### Quick Start with MCP
53
+
54
+ ```bash
55
+ # Start the MCP server
56
+ npx create-better-t-stack --mcp
57
+ ```
58
+
59
+ ### MCP Client Configuration
60
+
61
+ Add to your MCP client configuration:
62
+
63
+ ```json
64
+ {
65
+ "mcpServers": {
66
+ "better-t-stack": {
67
+ "command": "npx",
68
+ "args": ["-y", "create-better-t-stack", "--mcp"]
69
+ }
70
+ }
71
+ }
72
+ ```
73
+
74
+ ### Available MCP Tools
75
+
76
+ - **`create_project`** - Create a new Better-T Stack project with specified configuration
77
+ - **`list_configurations`** - List all available configuration options
78
+ - **`get_project_info`** - Get information about an existing project
79
+
80
+ For detailed MCP documentation, see [MCP_README.md](./MCP_README.md).
81
+
48
82
  ## Usage
49
83
 
50
84
  ```bash
package/dist/cli.js CHANGED
@@ -1,8 +1,426 @@
1
1
  #!/usr/bin/env node
2
- import { createBtsCli } from "./src-X-NzEC_t.js";
2
+ import { createBtsCli, init } from "./src-BN1_H4yj.js";
3
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
4
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
+ import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
3
6
 
7
+ //#region src/mcp-server.ts
8
+ const server = new Server({
9
+ name: "create-better-t-stack",
10
+ version: "1.0.0"
11
+ });
12
+ const createProjectTool = {
13
+ name: "create_project",
14
+ description: "Create a new Better-T Stack project with the specified configuration",
15
+ inputSchema: {
16
+ type: "object",
17
+ properties: {
18
+ projectName: {
19
+ type: "string",
20
+ description: "Name of the project to create"
21
+ },
22
+ database: {
23
+ type: "string",
24
+ enum: [
25
+ "none",
26
+ "sqlite",
27
+ "postgres",
28
+ "mysql",
29
+ "mongodb"
30
+ ],
31
+ description: "Database type to use"
32
+ },
33
+ orm: {
34
+ type: "string",
35
+ enum: [
36
+ "drizzle",
37
+ "prisma",
38
+ "mongoose",
39
+ "none"
40
+ ],
41
+ description: "ORM to use"
42
+ },
43
+ backend: {
44
+ type: "string",
45
+ enum: [
46
+ "hono",
47
+ "express",
48
+ "fastify",
49
+ "next",
50
+ "elysia",
51
+ "convex",
52
+ "none"
53
+ ],
54
+ description: "Backend framework to use"
55
+ },
56
+ runtime: {
57
+ type: "string",
58
+ enum: [
59
+ "bun",
60
+ "node",
61
+ "workers",
62
+ "none"
63
+ ],
64
+ description: "Runtime environment"
65
+ },
66
+ frontend: {
67
+ type: "array",
68
+ items: {
69
+ type: "string",
70
+ enum: [
71
+ "tanstack-router",
72
+ "react-router",
73
+ "tanstack-start",
74
+ "next",
75
+ "nuxt",
76
+ "native-nativewind",
77
+ "native-unistyles",
78
+ "svelte",
79
+ "solid",
80
+ "none"
81
+ ]
82
+ },
83
+ description: "Frontend frameworks to use"
84
+ },
85
+ addons: {
86
+ type: "array",
87
+ items: {
88
+ type: "string",
89
+ enum: [
90
+ "pwa",
91
+ "tauri",
92
+ "starlight",
93
+ "biome",
94
+ "husky",
95
+ "ruler",
96
+ "turborepo",
97
+ "fumadocs",
98
+ "ultracite",
99
+ "oxlint",
100
+ "none"
101
+ ]
102
+ },
103
+ description: "Addons to include"
104
+ },
105
+ examples: {
106
+ type: "array",
107
+ items: {
108
+ type: "string",
109
+ enum: [
110
+ "todo",
111
+ "ai",
112
+ "none"
113
+ ]
114
+ },
115
+ description: "Example templates to include"
116
+ },
117
+ auth: {
118
+ type: "boolean",
119
+ description: "Whether to include authentication"
120
+ },
121
+ git: {
122
+ type: "boolean",
123
+ description: "Whether to initialize git repository"
124
+ },
125
+ packageManager: {
126
+ type: "string",
127
+ enum: [
128
+ "npm",
129
+ "pnpm",
130
+ "bun"
131
+ ],
132
+ description: "Package manager to use"
133
+ },
134
+ install: {
135
+ type: "boolean",
136
+ description: "Whether to install dependencies"
137
+ },
138
+ dbSetup: {
139
+ type: "string",
140
+ enum: [
141
+ "turso",
142
+ "neon",
143
+ "prisma-postgres",
144
+ "mongodb-atlas",
145
+ "supabase",
146
+ "d1",
147
+ "docker",
148
+ "none"
149
+ ],
150
+ description: "Database setup configuration"
151
+ },
152
+ api: {
153
+ type: "string",
154
+ enum: [
155
+ "trpc",
156
+ "orpc",
157
+ "none"
158
+ ],
159
+ description: "API type to use"
160
+ },
161
+ webDeploy: {
162
+ type: "string",
163
+ enum: [
164
+ "vercel",
165
+ "netlify",
166
+ "wrangler",
167
+ "alchemy",
168
+ "none"
169
+ ],
170
+ description: "Web deployment platform"
171
+ },
172
+ serverDeploy: {
173
+ type: "string",
174
+ enum: [
175
+ "wrangler",
176
+ "alchemy",
177
+ "none"
178
+ ],
179
+ description: "Server deployment platform"
180
+ },
181
+ directoryConflict: {
182
+ type: "string",
183
+ enum: [
184
+ "merge",
185
+ "overwrite",
186
+ "increment",
187
+ "error"
188
+ ],
189
+ description: "How to handle directory conflicts"
190
+ },
191
+ yes: {
192
+ type: "boolean",
193
+ description: "Use default configuration without prompts"
194
+ },
195
+ yolo: {
196
+ type: "boolean",
197
+ description: "Bypass validations and compatibility checks"
198
+ },
199
+ verbose: {
200
+ type: "boolean",
201
+ description: "Show detailed result information"
202
+ },
203
+ disableAnalytics: {
204
+ type: "boolean",
205
+ description: "Disable analytics"
206
+ }
207
+ },
208
+ required: ["projectName"]
209
+ }
210
+ };
211
+ const listConfigurationsTool = {
212
+ name: "list_configurations",
213
+ description: "List available configurations for Better-T Stack projects",
214
+ inputSchema: {
215
+ type: "object",
216
+ properties: {}
217
+ }
218
+ };
219
+ const getProjectInfoTool = {
220
+ name: "get_project_info",
221
+ description: "Get information about a Better-T Stack project",
222
+ inputSchema: {
223
+ type: "object",
224
+ properties: { projectPath: {
225
+ type: "string",
226
+ description: "Path to the project directory"
227
+ } },
228
+ required: ["projectPath"]
229
+ }
230
+ };
231
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
232
+ return { tools: [
233
+ createProjectTool,
234
+ listConfigurationsTool,
235
+ getProjectInfoTool
236
+ ] };
237
+ });
238
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
239
+ const { name, arguments: args } = request.params;
240
+ switch (name) {
241
+ case "create_project": try {
242
+ const projectConfig = {
243
+ projectName: args?.projectName,
244
+ database: args?.database,
245
+ orm: args?.orm,
246
+ backend: args?.backend,
247
+ runtime: args?.runtime,
248
+ frontend: args?.frontend,
249
+ addons: args?.addons,
250
+ examples: args?.examples,
251
+ auth: args?.auth,
252
+ git: args?.git,
253
+ packageManager: args?.packageManager,
254
+ install: args?.install,
255
+ dbSetup: args?.dbSetup,
256
+ api: args?.api,
257
+ webDeploy: args?.webDeploy,
258
+ serverDeploy: args?.serverDeploy,
259
+ directoryConflict: args?.directoryConflict,
260
+ yes: args?.yes,
261
+ yolo: args?.yolo,
262
+ verbose: args?.verbose,
263
+ disableAnalytics: args?.disableAnalytics
264
+ };
265
+ const result = await init(args?.projectName, projectConfig);
266
+ return { content: [{
267
+ type: "text",
268
+ text: JSON.stringify(result, null, 2)
269
+ }] };
270
+ } catch (error) {
271
+ return {
272
+ content: [{
273
+ type: "text",
274
+ text: `Error creating project: ${error instanceof Error ? error.message : String(error)}`
275
+ }],
276
+ isError: true
277
+ };
278
+ }
279
+ case "list_configurations": {
280
+ const configurations = {
281
+ databases: [
282
+ "none",
283
+ "sqlite",
284
+ "postgres",
285
+ "mysql",
286
+ "mongodb"
287
+ ],
288
+ orms: [
289
+ "drizzle",
290
+ "prisma",
291
+ "mongoose",
292
+ "none"
293
+ ],
294
+ backends: [
295
+ "hono",
296
+ "express",
297
+ "fastify",
298
+ "next",
299
+ "elysia",
300
+ "convex",
301
+ "none"
302
+ ],
303
+ runtimes: [
304
+ "bun",
305
+ "node",
306
+ "workers",
307
+ "none"
308
+ ],
309
+ frontends: [
310
+ "tanstack-router",
311
+ "react-router",
312
+ "tanstack-start",
313
+ "next",
314
+ "nuxt",
315
+ "native-nativewind",
316
+ "native-unistyles",
317
+ "svelte",
318
+ "solid",
319
+ "none"
320
+ ],
321
+ addons: [
322
+ "pwa",
323
+ "tauri",
324
+ "starlight",
325
+ "biome",
326
+ "husky",
327
+ "ruler",
328
+ "turborepo",
329
+ "fumadocs",
330
+ "ultracite",
331
+ "oxlint",
332
+ "none"
333
+ ],
334
+ examples: [
335
+ "todo",
336
+ "ai",
337
+ "none"
338
+ ],
339
+ packageManagers: [
340
+ "npm",
341
+ "pnpm",
342
+ "bun"
343
+ ],
344
+ dbSetups: [
345
+ "turso",
346
+ "neon",
347
+ "prisma-postgres",
348
+ "mongodb-atlas",
349
+ "supabase",
350
+ "d1",
351
+ "docker",
352
+ "none"
353
+ ],
354
+ apis: [
355
+ "trpc",
356
+ "orpc",
357
+ "none"
358
+ ],
359
+ webDeploys: [
360
+ "vercel",
361
+ "netlify",
362
+ "wrangler",
363
+ "alchemy",
364
+ "none"
365
+ ],
366
+ serverDeploys: [
367
+ "wrangler",
368
+ "alchemy",
369
+ "none"
370
+ ],
371
+ directoryConflicts: [
372
+ "merge",
373
+ "overwrite",
374
+ "increment",
375
+ "error"
376
+ ]
377
+ };
378
+ return { content: [{
379
+ type: "text",
380
+ text: JSON.stringify(configurations, null, 2)
381
+ }] };
382
+ }
383
+ case "get_project_info": try {
384
+ return { content: [{
385
+ type: "text",
386
+ text: "Project info functionality not yet implemented"
387
+ }] };
388
+ } catch (error) {
389
+ return {
390
+ content: [{
391
+ type: "text",
392
+ text: `Error getting project info: ${error instanceof Error ? error.message : String(error)}`
393
+ }],
394
+ isError: true
395
+ };
396
+ }
397
+ default: throw new Error(`Unknown tool: ${name}`);
398
+ }
399
+ });
400
+ async function startMCPServer() {
401
+ const transport = new StdioServerTransport();
402
+ await server.connect(transport);
403
+ console.error("Better-T Stack MCP server started");
404
+ }
405
+ async function main$1() {
406
+ await startMCPServer();
407
+ }
408
+ if (import.meta.url === `file://${process.argv[1]}`) main$1().catch((error) => {
409
+ console.error("MCP server error:", error);
410
+ process.exit(1);
411
+ });
412
+
413
+ //#endregion
4
414
  //#region src/cli.ts
5
- createBtsCli().run();
415
+ async function main() {
416
+ const args = process.argv.slice(2);
417
+ if (args.includes("--mcp")) await startMCPServer();
418
+ else createBtsCli().run();
419
+ }
420
+ main().catch((error) => {
421
+ console.error("CLI error:", error);
422
+ process.exit(1);
423
+ });
6
424
 
7
425
  //#endregion
8
426
  export { };
package/dist/index.d.ts CHANGED
@@ -134,6 +134,7 @@ type CreateInput = {
134
134
  directoryConflict?: DirectoryConflict;
135
135
  renderTitle?: boolean;
136
136
  disableAnalytics?: boolean;
137
+ mcp?: boolean;
137
138
  };
138
139
  type AddInput = {
139
140
  addons?: Addons[];
@@ -221,6 +222,7 @@ declare const router: trpcServer.TRPCBuiltRouter<{
221
222
  directoryConflict?: "error" | "merge" | "overwrite" | "increment" | undefined;
222
223
  renderTitle?: boolean | undefined;
223
224
  disableAnalytics?: boolean | undefined;
225
+ mcp?: boolean | undefined;
224
226
  }];
225
227
  output: InitResult | undefined;
226
228
  meta: object;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import { builder, createBtsCli, docs, init, router, sponsors } from "./src-X-NzEC_t.js";
2
+ import { builder, createBtsCli, docs, init, router, sponsors } from "./src-BN1_H4yj.js";
3
3
 
4
4
  export { builder, createBtsCli, docs, init, router, sponsors };
@@ -1080,7 +1080,8 @@ async function getServerDeploymentChoice(deployment, runtime, backend, webDeploy
1080
1080
  if (backend === "none" || backend === "convex") return "none";
1081
1081
  if (backend !== "hono") return "none";
1082
1082
  const options = [];
1083
- if (runtime === "workers") ["alchemy", "wrangler"].forEach((deploy) => {
1083
+ if (runtime !== "workers") return "none";
1084
+ ["alchemy", "wrangler"].forEach((deploy) => {
1084
1085
  const { label, hint } = getDeploymentDisplay$1(deploy);
1085
1086
  options.unshift({
1086
1087
  value: deploy,
@@ -1088,11 +1089,6 @@ async function getServerDeploymentChoice(deployment, runtime, backend, webDeploy
1088
1089
  hint
1089
1090
  });
1090
1091
  });
1091
- else options.push({
1092
- value: "none",
1093
- label: "None",
1094
- hint: "Manual setup"
1095
- });
1096
1092
  const response = await select({
1097
1093
  message: "Select server deployment",
1098
1094
  options,
@@ -1123,11 +1119,7 @@ async function getServerDeploymentToAdd(runtime, existingDeployment, backend) {
1123
1119
  }
1124
1120
  }
1125
1121
  if (existingDeployment && existingDeployment !== "none") return "none";
1126
- if (options.length > 0) options.push({
1127
- value: "none",
1128
- label: "None",
1129
- hint: "Skip deployment setup"
1130
- });
1122
+ if (options.length > 0) {}
1131
1123
  if (options.length === 0) return "none";
1132
1124
  const response = await select({
1133
1125
  message: "Select server deployment",
@@ -1353,7 +1345,7 @@ const getLatestCLIVersion = () => {
1353
1345
  */
1354
1346
  function isTelemetryEnabled() {
1355
1347
  const BTS_TELEMETRY_DISABLED = process.env.BTS_TELEMETRY_DISABLED;
1356
- const BTS_TELEMETRY = "1";
1348
+ const BTS_TELEMETRY = "0";
1357
1349
  if (BTS_TELEMETRY_DISABLED !== void 0) return BTS_TELEMETRY_DISABLED !== "1";
1358
1350
  if (BTS_TELEMETRY !== void 0) return BTS_TELEMETRY === "1";
1359
1351
  return true;
@@ -1361,8 +1353,8 @@ function isTelemetryEnabled() {
1361
1353
 
1362
1354
  //#endregion
1363
1355
  //#region src/utils/analytics.ts
1364
- const POSTHOG_API_KEY = "phc_8ZUxEwwfKMajJLvxz1daGd931dYbQrwKNficBmsdIrs";
1365
- const POSTHOG_HOST = "https://us.i.posthog.com";
1356
+ const POSTHOG_API_KEY = "random";
1357
+ const POSTHOG_HOST = "random";
1366
1358
  function generateSessionId() {
1367
1359
  const rand = Math.random().toString(36).slice(2);
1368
1360
  const now = Date.now().toString(36);
@@ -1740,6 +1732,7 @@ function validateFullConfig(config, providedFlags, options) {
1740
1732
  validateApiConstraints(config, options);
1741
1733
  validateServerDeployRequiresBackend(config.serverDeploy, config.backend);
1742
1734
  validateWorkersCompatibility(providedFlags, options, config);
1735
+ if (config.runtime === "workers" && config.serverDeploy === "none") exitWithError("Cloudflare Workers runtime requires a server deployment. Please choose 'wrangler' or 'alchemy' for --server-deploy.");
1743
1736
  if (config.addons && config.addons.length > 0) {
1744
1737
  validateAddonsAgainstFrontends(config.addons, config.frontend);
1745
1738
  config.addons = [...new Set(config.addons)];
@@ -6327,7 +6320,8 @@ const router = t.router({
6327
6320
  serverDeploy: ServerDeploySchema.optional(),
6328
6321
  directoryConflict: DirectoryConflictSchema.optional(),
6329
6322
  renderTitle: z.boolean().optional(),
6330
- disableAnalytics: z.boolean().optional().default(false).describe("Disable analytics")
6323
+ disableAnalytics: z.boolean().optional().default(false).describe("Disable analytics"),
6324
+ mcp: z.boolean().optional().default(false).describe("Start as MCP server")
6331
6325
  })])).mutation(async ({ input }) => {
6332
6326
  const [projectName, options] = input;
6333
6327
  const combinedInput = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-better-t-stack",
3
- "version": "2.35.4",
3
+ "version": "2.35.5-canary.869063df",
4
4
  "description": "A modern CLI tool for scaffolding end-to-end type-safe TypeScript projects with best practices and customizable configurations",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -67,6 +67,7 @@
67
67
  "@biomejs/js-api": "^3.0.0",
68
68
  "@biomejs/wasm-nodejs": "^2.2.0",
69
69
  "@clack/prompts": "^0.11.0",
70
+ "@modelcontextprotocol/sdk": "^0.4.0",
70
71
  "consola": "^3.4.2",
71
72
  "execa": "^9.6.0",
72
73
  "fs-extra": "^11.3.1",