@nitrostack/cli 1.0.6 → 1.0.8

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.
Files changed (34) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +39 -96
  3. package/dist/commands/build.d.ts.map +1 -1
  4. package/dist/commands/build.js +4 -1
  5. package/dist/commands/dev.d.ts.map +1 -1
  6. package/dist/commands/dev.js +24 -52
  7. package/dist/commands/generate-types.d.ts +0 -1
  8. package/dist/commands/generate-types.d.ts.map +1 -1
  9. package/dist/commands/generate-types.js +18 -39
  10. package/dist/commands/generate.d.ts.map +1 -1
  11. package/dist/commands/generate.js +12 -4
  12. package/dist/commands/init.d.ts +3 -1
  13. package/dist/commands/init.d.ts.map +1 -1
  14. package/dist/commands/init.js +27 -15
  15. package/dist/commands/install.d.ts.map +1 -1
  16. package/dist/commands/install.js +3 -1
  17. package/dist/commands/start.d.ts.map +1 -1
  18. package/dist/commands/start.js +4 -4
  19. package/dist/commands/upgrade.d.ts.map +1 -1
  20. package/dist/commands/upgrade.js +92 -77
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +3 -1
  23. package/dist/ui/branding.d.ts +21 -4
  24. package/dist/ui/branding.d.ts.map +1 -1
  25. package/dist/ui/branding.js +121 -52
  26. package/package.json +5 -6
  27. package/templates/typescript-oauth/.env.example +27 -0
  28. package/templates/typescript-oauth/README.md +36 -231
  29. package/templates/typescript-pizzaz/.env.example +8 -0
  30. package/templates/typescript-pizzaz/README.md +42 -217
  31. package/templates/typescript-pizzaz/src/modules/pizzaz/pizzaz.module.ts +2 -1
  32. package/templates/typescript-pizzaz/src/modules/pizzaz/pizzaz.tasks.ts +294 -0
  33. package/templates/typescript-starter/.env.example +7 -0
  34. package/templates/typescript-starter/README.md +51 -284
@@ -0,0 +1,294 @@
1
+ /**
2
+ * Pizzaz Task Tools
3
+ *
4
+ * Demonstrates the MCP Tasks feature — long-running, async tool execution
5
+ * with progress reporting and cancellation support.
6
+ *
7
+ * To test via MCP Inspector (or any MCP client that supports tasks):
8
+ *
9
+ * tools/call name="audit_pizza_shops" task={}
10
+ * → returns { task: { taskId, status: "working", ... } }
11
+ *
12
+ * tasks/get taskId=<id>
13
+ * → returns current status & progress message
14
+ *
15
+ * tasks/result taskId=<id>
16
+ * → blocks until done, then returns the full audit report
17
+ *
18
+ * tasks/cancel taskId=<id>
19
+ * → cancels the running audit
20
+ */
21
+
22
+ import { ToolDecorator as Tool, ExecutionContext, Injectable, z } from '@nitrostack/core';
23
+ import { PizzazService } from './pizzaz.service.js';
24
+
25
+ // ─── Input Schemas ─────────────────────────────────────────────────────────
26
+
27
+ const AuditSchema = z.object({
28
+ /** Number of shops to audit. Defaults to all shops. */
29
+ maxShops: z
30
+ .number()
31
+ .int()
32
+ .min(1)
33
+ .max(20)
34
+ .optional()
35
+ .describe('Maximum number of pizza shops to audit (default: all)'),
36
+ /** Simulate a slow audit by adding a delay per shop in ms. */
37
+ delayPerShopMs: z
38
+ .number()
39
+ .int()
40
+ .min(0)
41
+ .max(5000)
42
+ .optional()
43
+ .default(800)
44
+ .describe('Simulated processing time per shop in milliseconds (default: 800ms)'),
45
+ });
46
+
47
+ const OrderPizzaSchema = z.object({
48
+ shopId: z.string().describe('ID of the pizza shop to order from'),
49
+ pizzaName: z.string().describe('Name of the pizza to order'),
50
+ quantity: z.number().int().min(1).max(10).default(1).describe('Number of pizzas to order'),
51
+ });
52
+
53
+ // ─── Helpers ────────────────────────────────────────────────────────────────
54
+
55
+ function sleep(ms: number): Promise<void> {
56
+ return new Promise((resolve) => setTimeout(resolve, ms));
57
+ }
58
+
59
+ /** Score a shop 0–100 based on rating and review count */
60
+ function scoreShop(shop: { rating: number; reviews: number; openNow: boolean }): number {
61
+ const ratingScore = (shop.rating / 5) * 60; // 60% weight
62
+ const reviewScore = Math.min(shop.reviews / 500, 1) * 30; // 30% weight
63
+ const openBonus = shop.openNow ? 10 : 0; // 10% bonus
64
+ return Math.round(ratingScore + reviewScore + openBonus);
65
+ }
66
+
67
+ function grade(score: number): string {
68
+ if (score >= 90) return 'A+';
69
+ if (score >= 80) return 'A';
70
+ if (score >= 70) return 'B';
71
+ if (score >= 60) return 'C';
72
+ return 'D';
73
+ }
74
+
75
+ // ─── Task Tools Controller ───────────────────────────────────────────────────
76
+
77
+ @Injectable({ deps: [PizzazService] })
78
+ export class PizzazTaskTools {
79
+ constructor(private readonly pizzazService: PizzazService) { }
80
+
81
+ /**
82
+ * audit_pizza_shops
83
+ *
84
+ * A long-running tool that audits every pizza shop in the database.
85
+ * It processes each shop one-by-one (with a configurable delay) so you
86
+ * can watch the progress messages update via tasks/get, then fetch the
87
+ * full report via tasks/result.
88
+ *
89
+ * taskSupport: 'optional' — works normally (sync) OR as a task.
90
+ * When invoked without `task: {}`, returns the audit immediately.
91
+ * When invoked with `task: {}`, returns a task handle immediately and
92
+ * runs the audit in the background.
93
+ */
94
+ @Tool({
95
+ name: 'audit_pizza_shops',
96
+ description:
97
+ 'Runs a quality audit across all pizza shops. ' +
98
+ 'This is a long-running operation — use task augmentation to run it asynchronously. ' +
99
+ 'Pass `task: {}` in your tools/call request to get a task handle, ' +
100
+ 'then poll with tasks/get and retrieve the report with tasks/result.',
101
+ inputSchema: AuditSchema,
102
+ taskSupport: 'optional',
103
+ examples: {
104
+ request: { maxShops: 3, delayPerShopMs: 0 },
105
+ response: {
106
+ summary: {
107
+ totalAudited: 3,
108
+ averageScore: 82,
109
+ topShop: 'Bella Napoli',
110
+ completedAt: '2025-01-01T00:00:00.000Z',
111
+ },
112
+ results: [
113
+ {
114
+ shopId: 'bella-napoli',
115
+ shopName: 'Bella Napoli',
116
+ score: 92,
117
+ grade: 'A+',
118
+ notes: 'Exceptional rating and review volume. Currently open.',
119
+ },
120
+ ],
121
+ },
122
+ },
123
+ })
124
+ async auditPizzaShops(
125
+ args: z.infer<typeof AuditSchema>,
126
+ ctx: ExecutionContext,
127
+ ) {
128
+ const allShops = this.pizzazService.getAllShops();
129
+ const shops = args.maxShops ? allShops.slice(0, args.maxShops) : allShops;
130
+ const delayMs = args.delayPerShopMs ?? 800;
131
+
132
+ ctx.logger.info('Starting pizza shop audit', {
133
+ totalShops: shops.length,
134
+ delayPerShopMs: delayMs,
135
+ isTask: !!ctx.task,
136
+ });
137
+
138
+ const results: Array<{
139
+ shopId: string;
140
+ shopName: string;
141
+ score: number;
142
+ grade: string;
143
+ notes: string;
144
+ }> = [];
145
+
146
+ for (let i = 0; i < shops.length; i++) {
147
+ const shop = shops[i];
148
+
149
+ // ── Cooperative cancellation check ──────────────────────────────
150
+ // If the client called tasks/cancel, we stop gracefully here
151
+ // instead of wasting time completing the rest of the audit.
152
+ if (ctx.task) {
153
+ ctx.task.throwIfCancelled();
154
+ ctx.task.updateProgress(
155
+ `🔍 Auditing "${shop.name}" (${i + 1}/${shops.length})…`,
156
+ );
157
+ }
158
+
159
+ // Simulate I/O-bound work (DB queries, external API calls, etc.)
160
+ await sleep(delayMs);
161
+
162
+ // Check again after the async work — client may have cancelled
163
+ if (ctx.task?.isCancelled) {
164
+ ctx.task.throwIfCancelled();
165
+ }
166
+
167
+ const score = scoreShop(shop);
168
+ const shopGrade = grade(score);
169
+
170
+ const notes: string[] = [];
171
+ if (score >= 90) notes.push('Exceptional rating and review volume.');
172
+ if (!shop.openNow) notes.push('Currently closed — may affect customer reach.');
173
+ if (shop.rating >= 4.7) notes.push('One of the highest-rated shops.');
174
+ if (shop.reviews < 100) notes.push('Low review count — still building reputation.');
175
+
176
+ results.push({
177
+ shopId: shop.id,
178
+ shopName: shop.name,
179
+ score,
180
+ grade: shopGrade,
181
+ notes: notes.join(' ') || 'Solid performer.',
182
+ });
183
+
184
+ ctx.logger.info(`Audited ${shop.name}: score=${score} (${shopGrade})`);
185
+ }
186
+
187
+ // Final progress update before completing
188
+ if (ctx.task) {
189
+ ctx.task.updateProgress(`✅ Audit complete! Compiling report for ${results.length} shops…`);
190
+ }
191
+
192
+ const averageScore =
193
+ results.length > 0
194
+ ? Math.round(results.reduce((sum, r) => sum + r.score, 0) / results.length)
195
+ : 0;
196
+
197
+ const topShop = results.sort((a, b) => b.score - a.score)[0];
198
+
199
+ return {
200
+ summary: {
201
+ totalAudited: results.length,
202
+ averageScore,
203
+ topShop: topShop?.shopName ?? 'N/A',
204
+ completedAt: new Date().toISOString(),
205
+ },
206
+ results,
207
+ };
208
+ }
209
+
210
+ /**
211
+ * order_pizza
212
+ *
213
+ * A task-REQUIRED tool — it MUST always be called with task: {} because
214
+ * orders involve payment processing and confirmation steps that take time.
215
+ * This demonstrates the 'required' task support level.
216
+ *
217
+ * Invoke: tools/call name="order_pizza" task={}
218
+ * arguments: { shopId: "bella-napoli", pizzaName: "Margherita", quantity: 2 }
219
+ */
220
+ @Tool({
221
+ name: 'order_pizza',
222
+ description:
223
+ 'Places an order at a pizza shop. This tool REQUIRES task augmentation — ' +
224
+ 'you must pass `task: {}` in your tools/call request. ' +
225
+ 'Poll with tasks/get and retrieve your order confirmation via tasks/result.',
226
+ inputSchema: OrderPizzaSchema,
227
+ taskSupport: 'required',
228
+ examples: {
229
+ request: { shopId: 'bella-napoli', pizzaName: 'Margherita', quantity: 1 },
230
+ response: {
231
+ orderId: 'ORD-12345',
232
+ status: 'confirmed',
233
+ estimatedMinutes: 30,
234
+ total: '$18.00',
235
+ items: [{ name: 'Margherita', quantity: 1, price: '$18.00' }],
236
+ },
237
+ },
238
+ })
239
+ async orderPizza(
240
+ args: z.infer<typeof OrderPizzaSchema>,
241
+ ctx: ExecutionContext,
242
+ ) {
243
+ const shop = this.pizzazService.getShopById(args.shopId);
244
+ if (!shop) {
245
+ throw new Error(`Pizza shop not found: ${args.shopId}`);
246
+ }
247
+
248
+ ctx.logger.info('Processing pizza order', {
249
+ shopId: args.shopId,
250
+ pizza: args.pizzaName,
251
+ quantity: args.quantity,
252
+ });
253
+
254
+ // Step 1 — validate stock
255
+ ctx.task?.updateProgress(`🛒 Checking availability of "${args.pizzaName}" at ${shop.name}…`);
256
+ await sleep(600);
257
+ ctx.task?.throwIfCancelled();
258
+
259
+ // Step 2 — process payment
260
+ ctx.task?.updateProgress(`💳 Processing payment…`);
261
+ await sleep(1000);
262
+ ctx.task?.throwIfCancelled();
263
+
264
+ // Step 3 — confirm with kitchen
265
+ ctx.task?.updateProgress(`🍕 Confirming order with kitchen…`);
266
+ await sleep(700);
267
+ ctx.task?.throwIfCancelled();
268
+
269
+ // Step 4 — dispatch
270
+ ctx.task?.updateProgress(`🚴 Order dispatched! Generating confirmation…`);
271
+ await sleep(300);
272
+
273
+ const pricePerPizza = shop.priceLevel * 9;
274
+ const total = pricePerPizza * args.quantity;
275
+
276
+ ctx.logger.info('Order confirmed', { shopId: args.shopId, total });
277
+
278
+ return {
279
+ orderId: `ORD-${Date.now().toString(36).toUpperCase()}`,
280
+ status: 'confirmed',
281
+ shop: shop.name,
282
+ estimatedMinutes: 25 + Math.floor(Math.random() * 15),
283
+ total: `$${total.toFixed(2)}`,
284
+ items: [
285
+ {
286
+ name: args.pizzaName,
287
+ quantity: args.quantity,
288
+ price: `$${(pricePerPizza * args.quantity).toFixed(2)}`,
289
+ },
290
+ ],
291
+ placedAt: new Date().toISOString(),
292
+ };
293
+ }
294
+ }
@@ -0,0 +1,7 @@
1
+ # NitroStack Starter Environment
2
+ # =============================================================================
3
+ # Add your environment variables here.
4
+ # =============================================================================
5
+
6
+ # Example:
7
+ # API_KEY=your_api_key_here
@@ -1,320 +1,87 @@
1
- # NitroStack Starter Template
1
+ # NitroStack Starter Template
2
2
 
3
- **The simple starter template** - Learn NitroStack fundamentals with a clean calculator example.
3
+ **The definitive starter template** Learn the fundamentals of the NitroStack MCP framework with a clean, well-documented calculator example.
4
4
 
5
5
  ## 🎯 What's Inside
6
6
 
7
- This template demonstrates core NitroStack features:
7
+ This template is designed to showcase core NitroStack features with zero friction:
8
8
 
9
- - **One Module** - Calculator module with all features
10
- - **One Tool** - `calculate` - Perform arithmetic operations
11
- - **One Resource** - `calculator://operations` - List of operations
12
- - **One Prompt** - `calculator_help` - Get usage help
13
- - **Two Widgets** - Beautiful UI for results and operations list
14
- - **No Authentication** - Focus on learning the basics
15
- - **No Database** - Pure computation example
9
+ - **Modular Architecture** Clean separation of concerns with a dedicated Calculator module.
10
+ - **Interactive Tools** A `calculate` tool for performing arithmetic operations.
11
+ - **Dynamic Resources** A `calculator://operations` resource for discovering capabilities.
12
+ - **Prompt Library** — Context-aware prompts for guiding users.
13
+ - **Pre-built UI Widgets** Beautiful, high-performance UI components for results and listings.
14
+ - **Production-Ready** Uses TypeScript, Zod for validation, and best-in-class logging.
16
15
 
17
- ## 🚀 Quick Start
18
-
19
- ### Prerequisites
16
+ ---
20
17
 
21
- ```bash
22
- # Install NitroStack CLI globally
23
- npm install -g nitrostack
18
+ ## 🚀 Quick Start
24
19
 
25
- # Or use npx
26
- npx nitrostack --version
27
- ```
20
+ ### 1. Initialize Your Project
28
21
 
29
- ### Setup Your Project
22
+ If you haven't already, scaffold your project using the NitroStack CLI:
30
23
 
31
24
  ```bash
32
- # Create a new project
33
- nitrostack init my-calculator --template typescript-starter
34
- cd my-calculator
35
-
36
- # Install all dependencies (root + widgets)
37
- nitrostack install
25
+ npx nitrostack init my-server --template typescript-starter
26
+ cd my-server
38
27
  ```
39
28
 
40
- That's it! The CLI automatically:
41
- - ✅ Installs all root dependencies
42
- - ✅ Installs widget dependencies
43
- - ✅ Sets up the project structure
29
+ ### 2. Install Dependencies
44
30
 
45
- ### Run the Project
31
+ Install all project dependencies (including the visual widget SDK) in one step:
46
32
 
47
33
  ```bash
48
- npm run dev
49
- ```
50
-
51
- This starts:
52
- - **MCP Server** (dual transport: STDIO + HTTP) - Hot reloads on code changes
53
- - **Studio** on http://localhost:3000 - Visual testing environment
54
- - **Widget Dev Server** on http://localhost:3001 - Hot module replacement
55
-
56
- > 💡 **Dual Transport**: Your server exposes tools via both STDIO (for direct connections) and HTTP (for remote access). Switch between transports in Studio → Settings.
57
-
58
- The `nitrostack dev` command handles everything automatically:
59
- - ✅ Auto-detects widget directory
60
- - ✅ Installs dependencies (if needed)
61
- - ✅ Builds widgets (on first run)
62
- - ✅ Starts all services concurrently
63
- - ✅ Hot reload for TypeScript and widgets
64
-
65
- ## 📁 Project Structure
66
-
34
+ npm run install:all
67
35
  ```
68
- src/
69
- ├── modules/
70
- │ └── calculator/
71
- │ ├── calculator.module.ts # @Module definition
72
- │ ├── calculator.tools.ts # @Tool with examples
73
- │ ├── calculator.resources.ts # @Resource
74
- │ └── calculator.prompts.ts # @Prompt
75
- ├── widgets/ # Next.js UI widgets
76
- │ └── app/
77
- │ ├── calculator-result/ # Tool result widget
78
- │ └── calculator-operations/ # Resource widget
79
- ├── app.module.ts # Root @McpApp module
80
- └── index.ts # Application bootstrap
81
- ```
82
-
83
- ## 🛠️ Available Features
84
-
85
- ### Health Check: `system`
86
36
 
87
- Monitors server health and resources:
37
+ ### 3. Get NitroStudio
88
38
 
89
- - **Uptime**: Server running time
90
- - **Memory Usage**: Heap memory consumption
91
- - **Process Info**: PID and Node.js version
92
- - **Status**: `up`, `degraded`, or `down`
39
+ NitroStudio is the recommended visual client for running, testing, and managing your NitroStack projects.
93
40
 
94
- Check health status in Studio's Health Checks tab!
41
+ 1. **Download NitroStudio**: [nitrostack.ai/studio](https://nitrostack.ai/studio)
42
+ 2. **Open Project**: Launch NitroStudio and open this project folder.
43
+ 3. **Run**: NitroStudio handles the rest!
95
44
 
96
- ### Tool: `calculate`
97
-
98
- Perform basic arithmetic operations:
99
-
100
- ```typescript
101
- @Tool({
102
- name: 'calculate',
103
- description: 'Perform basic arithmetic calculations',
104
- inputSchema: z.object({
105
- operation: z.enum(['add', 'subtract', 'multiply', 'divide']),
106
- a: z.number(),
107
- b: z.number()
108
- }),
109
- examples: {
110
- request: { operation: 'add', a: 5, b: 3 },
111
- response: { result: 8, expression: '5 + 3 = 8' }
112
- }
113
- })
114
- ```
115
-
116
- **Usage:**
117
- ```
118
- User: "Calculate 5 + 3"
119
- AI: [Calls calculate tool]
120
- Result: Beautiful widget showing "5 + 3 = 8"
121
- ```
122
-
123
- ### Resource: `calculator://operations`
124
-
125
- Lists all available operations with examples.
126
-
127
- ### Prompt: `calculator_help`
128
-
129
- Get help on how to use the calculator.
130
-
131
- ## 🎨 Widgets
132
-
133
- ### Calculator Result Widget
134
- - Gradient background
135
- - Operation icon
136
- - Breakdown of numbers
137
- - Beautiful animations
138
-
139
- ### Calculator Operations Widget
140
- - Grid of all operations
141
- - Color-coded by type
142
- - Examples for each operation
143
-
144
- ## 💡 Learning Path
145
-
146
- This template is perfect for learning:
45
+ ---
147
46
 
148
- 1. **Module Organization** - How to structure a feature module
149
- 2. **Tools** - How to create a tool with `@Tool` decorator
150
- 3. **Resources** - How to expose data with `@Resource`
151
- 4. **Prompts** - How to create conversation templates
152
- 5. **Widgets** - How to build UI components
153
- 6. **Examples** - How to include request/response examples
154
- 7. **Validation** - How to use Zod schemas
47
+ ## 🛠️ Development
155
48
 
156
- ## 🔧 Commands
49
+ If you prefer using the command line:
157
50
 
158
51
  ```bash
159
- # Installation
160
- npm install # Install all dependencies (root + widgets)
161
- nitrostack install # Same as above
162
-
163
- # Development
164
- npm run dev # Start dev server with Studio
165
- npm run build # Build TypeScript and widgets for production
166
- npm start # Run production server
167
-
168
- # Upgrade
169
- npm run upgrade # Upgrade nitrostack to latest version
170
-
171
- # Widget Management
172
- npm run widget <command> # Run npm command in widgets directory
173
- npm run widget add <pkg> # Add a widget dependency (e.g., @mui/material)
174
- ```
175
-
176
- ## 📝 Example Interactions
177
-
178
- ### Basic Calculation
179
- ```
180
- User: "What's 12 times 8?"
181
- AI: Calls calculate(operation="multiply", a=12, b=8)
182
- Result: Widget showing "12 × 8 = 96"
183
- ```
184
-
185
- ### Get Help
186
- ```
187
- User: "How do I use the calculator?"
188
- AI: Uses calculator_help prompt
189
- Result: Complete usage instructions
190
- ```
191
-
192
- ### List Operations
193
- ```
194
- User: "What operations are available?"
195
- AI: Fetches calculator://operations resource
196
- Result: Widget showing all 4 operations with examples
197
- ```
198
-
199
- ## 🎓 Code Walkthrough
200
-
201
- ### 1. Tool Definition
202
-
203
- ```typescript
204
- @Tool({
205
- name: 'calculate',
206
- description: 'Perform basic arithmetic calculations',
207
- inputSchema: z.object({...}),
208
- examples: {...}
209
- })
210
- @Widget('calculator-result') // Link UI widget
211
- async calculate(input: any, ctx: ExecutionContext) {
212
- // Your logic here
213
- return { result, expression };
214
- }
215
- ```
216
-
217
- **Key Points:**
218
- - `@Tool` decorator defines the tool
219
- - `inputSchema` validates input with Zod
220
- - `examples` help AI understand usage
221
- - `@Widget` links the UI component
222
- - `ExecutionContext` provides logger, metadata
223
-
224
- ### 2. Resource Definition
225
-
226
- ```typescript
227
- @Resource({
228
- uri: 'calculator://operations',
229
- name: 'Calculator Operations',
230
- mimeType: 'application/json',
231
- examples: {...}
232
- })
233
- @Widget('calculator-operations')
234
- async getOperations(uri: string, ctx: ExecutionContext) {
235
- return { contents: [{...}] };
236
- }
237
- ```
238
-
239
- ### 3. Prompt Definition
240
-
241
- ```typescript
242
- @Prompt({
243
- name: 'calculator_help',
244
- arguments: [...]
245
- })
246
- async getHelp(args: any, ctx: ExecutionContext) {
247
- return { messages: [...] };
248
- }
249
- ```
250
-
251
- ### 4. Module Definition
252
-
253
- ```typescript
254
- @Module({
255
- name: 'calculator',
256
- controllers: [CalculatorTools, CalculatorResources, CalculatorPrompts]
257
- })
258
- export class CalculatorModule {}
259
- ```
52
+ # Start development server (Server + Widgets + Studio)
53
+ npm run dev
260
54
 
261
- ### 5. Root Module
55
+ # Build for production
56
+ npm run build
262
57
 
263
- ```typescript
264
- @McpApp({
265
- server: { name: 'calculator-server', version: '1.0.0' }
266
- })
267
- @Module({
268
- imports: [ConfigModule.forRoot(), CalculatorModule]
269
- })
270
- export class AppModule {}
58
+ # Start production server
59
+ npm start
271
60
  ```
272
61
 
273
- ## 🚀 Extend This Template
274
-
275
- ### Add More Operations
276
-
277
- Edit `calculator.tools.ts` and add new operations to the enum and switch statement.
278
-
279
- ### Add History Feature
280
-
281
- 1. Create a service to store calculations
282
- 2. Add a `get_history` tool
283
- 3. Create a history widget
284
-
285
- ### Add More Modules
62
+ ## 📁 Project Structure
286
63
 
287
- ```bash
288
- nitrostack generate module converter
64
+ ```text
65
+ src/
66
+ ├── modules/
67
+ │ └── calculator/
68
+ │ ├── calculator.module.ts # @Module definition
69
+ │ ├── calculator.tools.ts # @Tool implementations
70
+ │ ├── calculator.resources.ts # @Resource definitions
71
+ │ └── calculator.prompts.ts # @Prompt templates
72
+ ├── widgets/ # Visual SDK UI components
73
+ ├── app.module.ts # Root application module
74
+ └── index.ts # Server entry point
289
75
  ```
290
76
 
291
- ## 📚 Next Steps
292
-
293
- Once you understand this template:
294
-
295
- 1. Try the **Pizza Shop Template** - Interactive maps and widgets
296
- 2. Try the **Flight Booking Template** - API integration with Duffel
297
- 3. Read the [NitroStack Documentation](https://nitrostack.ai/docs)
77
+ ## 🎨 Next Generation MCP
298
78
 
299
- ## 💡 Tips
79
+ NitroStack is more than just a server; it's a full-stack MCP ecosystem.
300
80
 
301
- - **Keep it Simple** - This template shows the minimum needed
302
- - **Study the Code** - Each file has clear examples
303
- - **Test in Studio** - Use the chat to test your tools
304
- - **Check Examples** - The `examples` field helps AI understand your tools
305
-
306
- ## 🎉 What to Build
307
-
308
- Use this as a starting point for:
309
-
310
- - **Unit Converters** - Temperature, currency, etc.
311
- - **Text Tools** - String manipulation, formatting
312
- - **Data Processors** - JSON, CSV, XML parsing
313
- - **Simple APIs** - Weather, jokes, facts
314
- - **Utilities** - Date/time, UUID generation
81
+ - **Website**: [nitrostack.ai](https://nitrostack.ai)
82
+ - **Documentation**: [docs.nitrostack.ai](https://docs.nitrostack.ai)
83
+ - **Discord**: [Join our community](https://nitrostack.ai/discord)
315
84
 
316
85
  ---
317
-
318
- **Happy Learning! 📖**
319
-
320
- Start simple, learn the patterns, then build something amazing!
86
+ **Happy Coding! 🎉**
87
+ Build something amazing with NitroStack.